From f0bd4152c7024073b31242d1bf8a9d656574b59b Mon Sep 17 00:00:00 2001 From: JordanViknar <74505993+JordanViknar@users.noreply.github.com> Date: Wed, 18 Sep 2024 10:01:46 +0200 Subject: [PATCH 1/5] feat: Program base rewrite --- .gitattributes | 2 + .gitignore | 45 -------- .luaurc | 12 +++ .vscode/settings.json | 11 ++ README.md | 108 -------------------- compressors/7z.lua | 158 ----------------------------- compressors/dolphin-tool.lua | 64 ------------ compressors/xz.lua | 68 ------------- extra/bannedExtensions.lua | 23 ----- extra/help.lua | 16 --- extra/programMetadata.lua | 6 -- init.luau | 1 + install/archlinux/PKGBUILD | 46 --------- modules/argumentManager.lua | 107 ------------------- modules/compressorManager.lua | 18 ---- modules/compressorObject.lua | 27 ----- modules/fsUtils.lua | 54 ---------- modules/logSystem.lua | 55 ---------- modules/systemUtils.lua | 43 -------- rokit.toml | 10 ++ selene.toml | 2 + smf | 24 ----- smf.lua | 152 --------------------------- src/Classes/Tool.luau | 16 +++ src/Metadata/BannedExtensions.luau | 17 ++++ src/Metadata/Help.luau | 15 +++ src/Metadata/Program.luau | 10 ++ src/Tools/init.luau | 5 + src/Utilities/Arguments.luau | 94 +++++++++++++++++ src/Utilities/Console.luau | 46 +++++++++ src/Utilities/Filesystem.luau | 13 +++ src/init.luau | 91 +++++++++++++++++ stylua.toml | 9 ++ 33 files changed, 354 insertions(+), 1014 deletions(-) create mode 100644 .gitattributes delete mode 100644 .gitignore create mode 100644 .luaurc create mode 100644 .vscode/settings.json delete mode 100644 README.md delete mode 100644 compressors/7z.lua delete mode 100644 compressors/dolphin-tool.lua delete mode 100644 compressors/xz.lua delete mode 100644 extra/bannedExtensions.lua delete mode 100644 extra/help.lua delete mode 100644 extra/programMetadata.lua create mode 100644 init.luau delete mode 100644 install/archlinux/PKGBUILD delete mode 100644 modules/argumentManager.lua delete mode 100644 modules/compressorManager.lua delete mode 100644 modules/compressorObject.lua delete mode 100644 modules/fsUtils.lua delete mode 100644 modules/logSystem.lua delete mode 100644 modules/systemUtils.lua create mode 100644 rokit.toml create mode 100644 selene.toml delete mode 100755 smf delete mode 100644 smf.lua create mode 100644 src/Classes/Tool.luau create mode 100644 src/Metadata/BannedExtensions.luau create mode 100644 src/Metadata/Help.luau create mode 100644 src/Metadata/Program.luau create mode 100644 src/Tools/init.luau create mode 100644 src/Utilities/Arguments.luau create mode 100644 src/Utilities/Console.luau create mode 100644 src/Utilities/Filesystem.luau create mode 100644 src/init.luau create mode 100644 stylua.toml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..179e626 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# LF normalization +* text=auto diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 1db00b9..0000000 --- a/.gitignore +++ /dev/null @@ -1,45 +0,0 @@ -# Compiled Lua sources -luac.out - -# luarocks build files -*.src.rock -*.zip -*.tar.gz - -# Object files -*.o -*.os -*.ko -*.obj -*.elf - -# Precompiled Headers -*.gch -*.pch - -# Libraries -*.lib -*.a -*.la -*.lo -*.def -*.exp - -# Shared objects (inc. Windows DLLs) -*.dll -*.so -*.so.* -*.dylib - -# Executables -*.exe -*.out -*.app -*.i*86 -*.x86_64 -*.hex - -# Custom - -# Visual Studio Code -.vscode/* diff --git a/.luaurc b/.luaurc new file mode 100644 index 0000000..3240e06 --- /dev/null +++ b/.luaurc @@ -0,0 +1,12 @@ +{ + "languageMode": "strict", + "lint": { + "*": false + }, + "aliases": { + "Metadata" : "src/Metadata", + "Utilities" : "src/Utilities", + "Classes" : "src/Classes", + "Tools" : "src/Tools" + } +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a6590ae --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "luau-lsp.require.mode": "relativeToFile", + "luau-lsp.require.directoryAliases": { + "@lune/": "~/.lune/.typedefs/0.8.8/", + "@Metadata": "src/Metadata", + "@Utilities": "src/Utilities", + "@Classes": "src/Classes", + "@Tools": "src/Tools" + }, + "luau-lsp.sourcemap.enabled": false +} \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index b8600aa..0000000 --- a/README.md +++ /dev/null @@ -1,108 +0,0 @@ -*One day, [Jordan](https://github.com/JordanViknar) decided he had enough of wasting storage space on files he barely used.* - -*What if a tool existed that could **easily** crush anything in its path ? And thus came onto the world...* - ---- - -# StompMyFiles - -Universal file compression utility, aiming for brute strength (at the cost of time) and ease of use. Made in Lua. - -![License](https://img.shields.io/github/license/JordanViknar/StompMyFiles?color=orange) -![Top language](https://img.shields.io/github/languages/top/JordanViknar/StompMyFiles?color=blue) -![Commit activity](https://img.shields.io/github/commit-activity/m/JordanViknar/StompMyFiles?color=orange) -![Repo size](https://img.shields.io/github/repo-size/JordanViknar/StompMyFiles) - -(Currently) available for : - -![Linux](https://img.shields.io/badge/Linux-FCC624?style=for-the-badge&logo=linux&logoColor=black) -![Arch Linux](https://img.shields.io/badge/Arch_Linux-1793D1?style=for-the-badge&logo=arch-linux&logoColor=white) -![Manjaro](https://img.shields.io/badge/manjaro-35BF5C?style=for-the-badge&logo=manjaro&logoColor=white) - -## Goals - -StompMyFiles aims to be : -- **Powerful**, no matter the cost : StompMyFiles' first aim is to compress files given to it as hard as it can, under the best known method available depending on the file's type. -- **Extremely simple to use** : You give it a file, it replaces it with its compressed version if possible. There's **nothing** more to it. -- **Lossless** : Every single piece of data originally present must be able to be restored from StompMyFiles, with just the compressed file itself. - -*Note : StompMyFiles focuses so heavily on compression strength that it's pretty CPU and RAM intensive, and may even be slow in a few cases. As such, it may not always be the best fit for your use case.* - -## Installation - -### Arch Linux-based distributions - -StompMyFiles can be installed from Arch Linux through the provided [PKGBUILD](https://github.com/JordanViknar/StompMyFiles/blob/main/install/archlinux/PKGBUILD). - -**Always** download the latest version of the PKGBUILD, then use **makepkg** in its directory. - -It will eventually be made available on the AUR once the program is complete enough. - -### I want to add support for my own distribution ! - -Here are informations which might be useful to you : - -StompMyFiles is meant to be installed in `/usr/share/stomp-my-files` (except `smf` which goes into `/usr/bin`). - -It depends on : -- Lua 5.4 *(5.3 and 5.2 MIGHT work)* -- [LuaFileSystem](https://github.com/lunarmodules/luafilesystem) -- [LuaSocket](https://github.com/lunarmodules/luasocket) + [LuaSec](https://github.com/lunarmodules/luasec) -- Common tools such as : *which*, *tar*, *grep*, *xz* - -And optionally : -- 7-zip / p7zip : If the system doesn't provide them, StompMyFiles will download them if possible. -- Dolphin Emulator : StompMyFiles uses *dolphin-tool* to compress Nintendo Wii/GameCube games. - -### Manual local installation (not recommended except for development) - -Install the aforementioned dependencies on your system, clone the repository, and run `./smf`, assuming you're in the program's directory. - -## Usage - -``` -smf [OPTIONS] FILES ... -``` - -Available options : -- `--help` : Displays StompMyFiles' help page -- `--verbose` : Used for debugging. Makes StompMyFiles more explicit about what it's doing. -- `--version` : Reports StompMyFiles' version and shows a small description. - -ISO file specific options (if none of these are specified, StompMyFiles will skip them) : -- `--iso` : Tells StompMyFiles to treat ISO files normally. -- `--wii-gc` : Tells StompMyFiles to treat ISO files as Wii/GameCube games. - -## Support - -| Tool | Local Download | Compression / Decompression | Used for | -| ---- | -------------- | --------------------------- | -------- | -| 7z | ✅ | ✅ | Folders | -| xz | ❌ | ✅ | Default choice for single files | -| dolphin-tool | ❌ | ✅ | Nintendo Wii / GameCube games (requires Dolphin Emulator to be installed) | -| nsz | *Planned* | *Planned* | Nintendo Switch games | -| upx | *Planned ?* | *Planned ?* | Executables | - -## Compression Test Results - -### Personal Files - -| Up-to-date | File(s) | Tool | Original Size | SMF Output | Percentage | -| ---------- | ------- | ---- | ------------- | ---------- | ---------- | -| ✅ | First Year of Pre-Engineering | 7z | 579.8 Mo | 431.1 Mo | 74 % | -| ✅ | Second Year of Pre-Engineering | 7z | 1.1 Go | 731.9 Mo | 67 % | - -### Applications / Games - -| Up-to-date | Application | Type | Tool | Original Size | SMF Output | Percentage | -| ---------- | ----------- | ---- | ---- | ------------- | ---------- | ---------- | -| ✅ | Celeste | Steam Game (Linux) | 7z | 1.2 Go | 770.6 Mo | 64 % | -| ✅ | Um Jammer Lammy | PlayStation 1 Game | xz | 743.5 Mo | 499.5 Mo | 67 % | -| ✅ | Super Smash Bros. Brawl | Wii Game | dolphin-tool | 8.5 Go | 5.8 Go | 68 % | -| ✅ | Rayman Redemption | Windows Game | 7z | 1.3 Go | 879.8 Mo | 68 % | -| ✅ | Pizza Tower | Steam Game (Windows) | 7z | 256.8 Mo | 185.4 Mo | 72 % | - -## Bug Reports / Contributions / Suggestions -You can report bugs or suggest features by making an issue, or you can contribute to this program directly by forking it and then sending a pull request. - -Any help will be very much appreciated. Thank you. \ No newline at end of file diff --git a/compressors/7z.lua b/compressors/7z.lua deleted file mode 100644 index 5af7d84..0000000 --- a/compressors/7z.lua +++ /dev/null @@ -1,158 +0,0 @@ --- External modules -local socket = require("socket.http") -local lfs = require("lfs") - --- Custom modules -local logSystem = require("modules.logSystem") -local Compressor = require("modules.compressorObject") -local compressorManager = require("modules.compressorManager") -local fsUtils = require("modules.fsUtils") -local systemUtils = require("modules.systemUtils") - --- Definitions -local compressorName = "7z" -local localVersion = "2301" - -local function checkFunction() - if (os.execute("which "..compressorName.." > /dev/null 2>&1") == true and ARGUMENTS.settings.ignoreSystemLibs == false) then - return "system" - else - logSystem.log("warning", "7z can't be provided by your system. Checking local cache...") - - -- Make 7z folder in cache if missing - if (not fsUtils.exists(CACHE_FOLDER..compressorName)) then - logSystem.log("debug", "Creating 7z folder in cache...") - lfs.mkdir(CACHE_FOLDER.."7z") - end - - -- Check if the local version is present or updated - if (fsUtils.exists(CACHE_FOLDER.."7z/version.txt")) then - local f = io.open(CACHE_FOLDER.."7z/version.txt", "r") - if (f) then - local version = f:read("*a") - f:close() - if (version == localVersion.."\n") then - logSystem.log("download", "7z is already installed into the local cache.") - return "local" - else - logSystem.log("download", "7z is installed into the local cache, but it's outdated.") - end - end - else - logSystem.log("warning", "7z is unavailable from system and local cache.") - end - - -- Check if we have internet - if (not systemUtils.isInternetAvailable()) then - return "unavailable" - end - - -- First we set what processor platform we're on - local platform = systemUtils.checkPlatform() - if (not platform) then - return "unavailable" - end - - -- Download 7zip and put its executable in the local cache - logSystem.log("download", "Downloading 7z into local cache...") - local response, status, headers = socket.request("https://www.7-zip.org/a/7z"..localVersion.."-linux-"..platform..".tar.xz") - if status == 200 then - -- If we succeed, we save the downloaded content to a file - local file = io.open(CACHE_FOLDER..compressorName.."/7z-linux-"..platform..".tar.xz", "wb") - - if file then - file:write(response) - file:close() - logSystem.log("debug", "Downloaded 7z.") - else - logSystem.log("error", "Failed to save the downloaded content to a file.") - return "unavailable" - end - else - logSystem.log("error", "Failed to download 7z : HTTP status code " .. status) - return "unavailable" - end - - -- Extract the archive - logSystem.log("debug", "Extracting 7z...") - local extractCommand = string.format("tar -xf '%s' -C '%s' '%s'", - CACHE_FOLDER..compressorName.."/"..compressorName.."-linux-"..platform..".tar.xz", - CACHE_FOLDER..compressorName, - "7zz" - ) - logSystem.log("debug", "Running command : "..extractCommand) - os.execute(extractCommand) - - -- Remove the archive - logSystem.log("debug", "Removing 7z archive...") - os.remove(CACHE_FOLDER..compressorName.."/7z-linux-"..platform..".tar.xz") - - -- Rename 7zz executable into 7z - logSystem.log("debug", "Renaming 7zz executable into 7z...") - os.execute("mv '"..CACHE_FOLDER.."7z/7zz' '"..CACHE_FOLDER.."7z/7z'") - - -- Make the executable executable - logSystem.log("debug", "Making 7z executable...") - os.execute("chmod +x '"..CACHE_FOLDER.."7z/7z'") - - -- Add a text file with the version - logSystem.log("debug", "Adding version information...") - os.execute("echo '"..localVersion.."' > '"..CACHE_FOLDER.."7z/version.txt'") - - logSystem.log("download", "7z was downloaded and installed into the local cache.") - return "local" - end -end - -local function compressFunction(input) - --Get number of CPU threads - logSystem.log("debug", "Getting number of CPU threads for 7z...") - local f = io.popen("cat /proc/cpuinfo | grep processor | wc -l") - if (not f) then - error("Could not get the number of CPU threads.") - end - local threads = f:read("*a") - f:close() - threads = tonumber(threads) - logSystem.log("debug", "Got "..threads.." threads.") - - -- Compress - logSystem.log("info", "Compressing "..input.." using 7z with "..threads.." threads.") - local command = string.format("%s -sdel -mx9 -ms=on -mmt%s a '%s.7z' '%s' ", - compressorManager.selectCompressionTool("7z"), - threads, - input:gsub("'", "'\\''"), - input:gsub("'", "'\\''") - ) - logSystem.log("debug", "Running command : "..command) - logSystem.log("switch", "Passing output to 7z...") - os.execute(command) - logSystem.log("switchEnd") - return "success" -end - -local function decompressFunction(input) - -- Decompress - logSystem.log("info", "Decompressing "..input.." using 7z.") - local command = string.format("%s x '%s' -o'%s'", - compressorManager.selectCompressionTool("7z"), - input:gsub("'", "'\\''"), - fsUtils.getDirectory(input):gsub("'", "'\\''") - ) - logSystem.log("debug", "Running command : "..command) - logSystem.log("switch", "Passing output to 7z...") - local result = os.execute(command) - logSystem.log("switchEnd") - - if result == true then - logSystem.log("debug", "Removing archive...") - os.remove(input:gsub("'", "'\\''")) - else - logSystem.log("error", "7z returned an error code. Archive file won't be removed.") - return "error" - end - return "success" -end - - -return Compressor:new(compressorName, checkFunction, compressFunction, decompressFunction) diff --git a/compressors/dolphin-tool.lua b/compressors/dolphin-tool.lua deleted file mode 100644 index e02c067..0000000 --- a/compressors/dolphin-tool.lua +++ /dev/null @@ -1,64 +0,0 @@ --- Custom modules -local logSystem = require("modules.logSystem") -local Compressor = require("modules.compressorObject") -local compressorManager = require("modules.compressorManager") -local fsUtils = require("modules.fsUtils") - --- Definitions -local compressorName = "dolphin-tool" -local localVersion = nil - -local function checkFunction() - if (os.execute("which "..compressorName.." > /dev/null 2>&1") == true and ARGUMENTS.settings.ignoreSystemLibs == false) then - return "system" - else - logSystem.log( - "error", - "dolphin-tool can't be provided by your system or locally. Wii/GameCube disc image support won't be available." - ) - return "unavailable" - end -end - -local function compressFunction(input) - logSystem.log("info", "Compressing "..input.." using dolphin-tool.") - - local command = string.format("%s convert -f rvz -c lzma2 -l 9 -b 2097152 -i '%s' -o '%s'", - compressorManager.selectCompressionTool("dolphin-tool"), - input:gsub("'", "'\\''"), - (fsUtils.getDirectory(input).."/"..fsUtils.getFileNameNoExt(input)..".rvz"):gsub("'", "'\\''") - ) - logSystem.log("debug", "Running command : "..command) - - if os.execute(command) == true then - logSystem.log("debug", "Removing ISO file...") - os.remove(input:gsub("'", "'\\''")) - else - logSystem.log("error", "dolphin-tool returned an error code. ISO file won't be removed.") - return "error" - end - return "success" -end - -local function decompressFunction(input) - logSystem.log("info", "Decompressing "..input.." using dolphin-tool.") - - local command = string.format("%s convert -f iso -i '%s' -o '%s'", - compressorManager.selectCompressionTool("dolphin-tool"), - input:gsub("'", "'\\''"), - (fsUtils.getDirectory(input).."/"..fsUtils.getFileNameNoExt(input)..".iso"):gsub("'", "'\\''") - ) - logSystem.log("debug", "Running command : "..command) - - if os.execute(command) == true then - logSystem.log("debug", "Removing RVZ file...") - os.remove(input:gsub("'", "'\\''")) - else - logSystem.log("error", "dolphin-tool returned an error code. RVZ file won't be removed.") - return "error" - end - - return "success" -end - -return Compressor:new(compressorName, checkFunction, compressFunction, decompressFunction) diff --git a/compressors/xz.lua b/compressors/xz.lua deleted file mode 100644 index b135a0b..0000000 --- a/compressors/xz.lua +++ /dev/null @@ -1,68 +0,0 @@ --- Custom modules -local logSystem = require("modules.logSystem") -local Compressor = require("modules.compressorObject") -local compressorManager = require("modules.compressorManager") - --- Functions -local function getMemoryToUse() - -- Allow xz to use 60% of the available RAM - logSystem.log("debug", "Getting amount of RAM available for XZ...") - local f = io.popen("free -m") - if (not f) then - error("Could not get the amount of RAM available.") - end - local ram = f:read("*a") - f:close() - ram = ram:match("Mem:%s+(%d+)") - ram = math.floor(ram * 0.6) - logSystem.log("debug", "Got "..ram.."GB of RAM.") - - return ram -end - --- Definitions -local compressorName = "xz" -local localVersion = nil - -local function checkFunction() - if (os.execute("which "..compressorName.." > /dev/null 2>&1") == true and ARGUMENTS.settings.ignoreSystemLibs == false) then - return "system" - else - logSystem.log( - "error", - "XZ can't be provided by your system or locally. Default file compression/decompression support unavailable." - ) - return "unavailable" - end -end - -local function compressFunction(input) - local ram = getMemoryToUse() - - logSystem.log("info", "Compressing "..input.." using XZ with "..ram.."GB of RAM.") - local command = string.format("%s -z9e --threads=0 --memlimit=%sGB '%s'", - compressorManager.selectCompressionTool("xz"), - ram, - input:gsub("'", "'\\''") - ) - logSystem.log("debug", "Running command : "..command) - os.execute(command) - return "success" -end - -local function decompressFunction(input) - local ram = getMemoryToUse() - - logSystem.log("info", "Decompressing "..input.." using XZ with "..ram.."GB of RAM.") - local command = string.format("%s -d --threads=0 --memlimit=%sGB '%s'", - compressorManager.selectCompressionTool("xz"), - ram, - input:gsub("'", "'\\''") - ) - logSystem.log("debug", "Running command : "..command) - os.execute(command) - return "success" -end - - -return Compressor:new(compressorName, checkFunction, compressFunction, decompressFunction) diff --git a/extra/bannedExtensions.lua b/extra/bannedExtensions.lua deleted file mode 100644 index 3d69adb..0000000 --- a/extra/bannedExtensions.lua +++ /dev/null @@ -1,23 +0,0 @@ -local bannedExtensions = { - -- Lossy compressed picture formats - "jpg", - "jpeg", - - -- Lossy compressed audio formats - "mp3", - "opus", - "aac", - - -- Unsupported compressed files - "zip", - "rar", - "zstd", - "gz", - "bz2" -} - -local bannedExtensionsDict = {} -for _,i in ipairs(bannedExtensions) do - bannedExtensionsDict[i] = true -end -return bannedExtensionsDict diff --git a/extra/help.lua b/extra/help.lua deleted file mode 100644 index 05847bf..0000000 --- a/extra/help.lua +++ /dev/null @@ -1,16 +0,0 @@ -local help = NAME.." Help Page\ -\ -Usage : "..EXECUTABLE.." [OPTIONS]... FILES\ -(Yes, that's it. It's that simple.)\ -\ -Arguments :\ - --help : Displays this help page.\ - --verbose : Enable debug messages.\ - --version : Displays the version of the program.\ - --ignore-system : Ignore system executables.\ -\ - --iso : Treat ISOs as normal files.\ - --wii-gc : Treat ISOs as Wii/GameCube games.\ -" - -print(help) diff --git a/extra/programMetadata.lua b/extra/programMetadata.lua deleted file mode 100644 index 5a5f42f..0000000 --- a/extra/programMetadata.lua +++ /dev/null @@ -1,6 +0,0 @@ -NAME = "StompMyFiles" -EXECUTABLE = "smf" -VERSION = "indev" -DEVELOPER = "JordanViknar" -URL = "https://github.com/JordanViknar/StompMyFiles" -CACHE_FOLDER = os.getenv("HOME").."/.cache/stomp-my-files/" diff --git a/init.luau b/init.luau new file mode 100644 index 0000000..bf2879c --- /dev/null +++ b/init.luau @@ -0,0 +1 @@ +return require('./src').start() diff --git a/install/archlinux/PKGBUILD b/install/archlinux/PKGBUILD deleted file mode 100644 index deaee7f..0000000 --- a/install/archlinux/PKGBUILD +++ /dev/null @@ -1,46 +0,0 @@ -# Maintainer: JordanViknar - -pkgname=stomp-my-files-git -pkgver=r2.5abd7f2 -pkgrel=1 -pkgdesc="Universal file compression utility, aiming for brute strength (at the cost of time) and ease of use." -arch=('x86_64' 'i686' 'armv7h' 'aarch64') -url=https://github.com/JordanViknar/StompMyFiles -license=(MPL-2.0) -depends=( - 'lua' - 'lua-filesystem' # Used for some filesystem operations - 'lua-socket' # Used for pings and downloads - 'lua-sec' # Used for secure https downloads - 'which' - 'tar' # Used to unpack downloads - 'grep' - 'xz' -) -optdepends=( - 'p7zip: Use 7z system installation for compression' - 'dolphin-emu: Enable Wii/GameCube compression through dolphin-tool' - 'upx: (Not used yet) Use UPX system installation for compression' - 'nsz: (Not used yet) Use NSZ system installation for compression' -) -makedepends=(git) -provides=("${pkgname%-git}") -conflicts=("${pkgname%-git}") -source=("StompMyFiles::git+https://github.com/JordanViknar/StompMyFiles") -md5sums=(SKIP) - -pkgver() { - cd "$srcdir/StompMyFiles" - printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)" -} - -package() { - app_directory="${srcdir}/StompMyFiles" - install_directory="${pkgdir}/usr/share/stomp-my-files" - - install -D "${app_directory}/smf" "${pkgdir}/usr/bin/smf" - install -D "${app_directory}/smf.lua" "${install_directory}/smf.lua" - cp -r "${app_directory}/modules" "${install_directory}/modules" - cp -r "${app_directory}/extra" "${install_directory}/extra" - cp -r "${app_directory}/compressors" "${install_directory}/compressors" -} diff --git a/modules/argumentManager.lua b/modules/argumentManager.lua deleted file mode 100644 index 5320480..0000000 --- a/modules/argumentManager.lua +++ /dev/null @@ -1,107 +0,0 @@ --- Custom Modules -local logSystem = require("modules.logSystem") -local fsUtils = require("modules.fsUtils") - --- Variables - --- Determines how ISOs are treated. nil = not specified, "iso" = normal ISO, "wii_gc" = Wii/GameCube ISO -local isoMode = nil - -local ignoreSystemLibs = false -- Determines whether or not to ignore system libraries. -local verboseEnabled = false -- Determines whether or not to print debug messages. - --- First, we give each argument an action. -local arguments = { - ["--ignore-system"] = function () - ignoreSystemLibs = true - end, - ["--help"] = function () - require("extra.help") - os.exit(0) - end, - ["--iso"] = function() - if isoMode == nil then - logSystem.log("info", "ISOs will be treated normally.") - isoMode = "iso" - elseif isoMode ~= "iso" then - logSystem.log("error", "ISOs are already treated as something else.") - os.exit(1) - end - end, - ["--wii-gc"] = function() - if isoMode == nil then - print() - print("----------------------------------------------------------------------------") - print("WARNING ! StompMyFiles aims for pure brute strength, not performance !") - print("Wii/GameCube games compressed with it may not perform well or malfunction until decompression.") - print("----------------------------------------------------------------------------") - io.write("Press Enter to confirm you've read this prompt.") - io.read() - print() - - logSystem.log("info", "ISOs will be treated as Wii/GameCube games.") - isoMode = "wii_gc" - elseif isoMode ~= "wii_gc" then - logSystem.log("error", "ISOs are already treated as something else.") - os.exit(1) - end - end, - ["--verbose"] = function () - verboseEnabled = true - end, - ["--version"] = function () - print("\27[33m"..NAME.." version "..VERSION.."\27[0m") - print("Universal file compression utility, aiming for brute strength (at the cost of time) and ease of use.") - print("(Also useful if you're freezing, since it may set your CPU or RAM on fire)") - print("") - print("Developed by \27[91m"..DEVELOPER.."\27[0m") - print("\27[34m"..URL.."\27[0m") - os.exit(0) - end -} - --- And finally, the argument management -local toBeCompressed = {} -for _,i in ipairs(arg) do - local f = arguments[i] - if (f) then - -- If the argument exists, we execute it. - f() - else - if (i:sub(1,1) == "-") then - logSystem.log("error", "Unknown argument "..i) - os.exit(1) - end - - -- Else we assume the user is trying to open a file. - if fsUtils.exists(i) then - -- We check that it isn't already in the table - local checkIfInTable = function () - for _,j in ipairs(toBeCompressed) do - if (j == i) then - return true - end - end - return false - end - - if (not checkIfInTable()) then - table.insert(toBeCompressed, i) - else - logSystem.log("info", "File "..i.." is already in the list. Skipping...") - end - elseif (i ~= "") then --Workaround around Bash shenanigans - logSystem.log("warning", "File "..i.." does not exist. Skipping...") - end - end -end -if (#toBeCompressed == 0) then - logSystem.log("error", "No valid input file specified.") - os.exit(1) -end - -return {toBeCompressed = toBeCompressed, settings = { - isoMode = isoMode, - ignoreSystemLibs = ignoreSystemLibs, - verboseEnabled = verboseEnabled -}} diff --git a/modules/compressorManager.lua b/modules/compressorManager.lua deleted file mode 100644 index b1c6a7c..0000000 --- a/modules/compressorManager.lua +++ /dev/null @@ -1,18 +0,0 @@ --- Custom Modules -local fsUtils = require("modules.fsUtils") - --- Definitions -local compressorManager = {} - -function compressorManager.selectCompressionTool(compressorType) - local systemTest = os.execute("which "..compressorType.." > /dev/null 2>&1") - if ((systemTest == 0 or systemTest == true) and ARGUMENTS.settings.ignoreSystemLibs == false) then - return compressorType - elseif(fsUtils.exists(CACHE_FOLDER..compressorType.."/"..compressorType)) then - return CACHE_FOLDER..compressorType.."/"..compressorType - else - error("Could not find "..compressorType.." in the system or in the local cache.") - end -end - -return compressorManager diff --git a/modules/compressorObject.lua b/modules/compressorObject.lua deleted file mode 100644 index 4bb5390..0000000 --- a/modules/compressorObject.lua +++ /dev/null @@ -1,27 +0,0 @@ --- Custom modules -local logSystem = require("modules.logSystem") - -Compressor = { - metatable = { - __index = Compressor - } -} -function Compressor:new (name, checkCommand, compressCommand, decompressCommand) - return setmetatable({ - name = name, - compress = compressCommand or function() - logSystem.log("warning","No compression command defined for "..name..". Skipping...") - return "notDefined" - end, - check = checkCommand or function() - logSystem.log("warning","No avaibility checks defined for "..name..". Attempting operation anyways...") - return "notDefined" - end, - decompress = decompressCommand or function() - logSystem.log("warning","No decompression command defined for "..name..". Skipping...") - return "notDefined" - end, - }, Compressor.metatable) -end - -return Compressor diff --git a/modules/fsUtils.lua b/modules/fsUtils.lua deleted file mode 100644 index b079efb..0000000 --- a/modules/fsUtils.lua +++ /dev/null @@ -1,54 +0,0 @@ --- External Modules -local lfs = require("lfs") - --- Module -local fsUtils = {} - ---- Check if a file or directory exists -function fsUtils.exists(path) - local attributes, err = lfs.attributes(path) - if attributes then - return true - else - return false, err - end -end - --- Get the file extension -function fsUtils.getExtension(path) - return path:match(".+%.(.+)") -end - --- Check if it's a folder -function fsUtils.isDirectory(path) - local attributes, err = lfs.attributes(path) - if attributes and attributes.mode == "directory" then - return true - else - return false, err - end -end - --- Grab file name -function fsUtils.getFileName(path) - local filename = path:match("^.+/(.+)$") - if filename then - return filename - else - return path - end -end - --- Grab file name without extension -function fsUtils.getFileNameNoExt(path) - local filename = fsUtils.getFileName(path) - return filename:match("(.+)%..+") or filename -end - --- Grab directory -function fsUtils.getDirectory(path) - local directory = path:match("^(.+)/[^/]+$") - return directory or "." -end - -return fsUtils diff --git a/modules/logSystem.lua b/modules/logSystem.lua deleted file mode 100644 index dee4778..0000000 --- a/modules/logSystem.lua +++ /dev/null @@ -1,55 +0,0 @@ -local logSystem = {} - -local function color(colorId, message) - local colorList = { - ["red"] = "\27[31m", - ["green"] = "\27[32m", - ["yellow"] = "\27[33m", - ["blue"] = "\27[34m", - ["magenta"] = "\27[35m", - ["cyan"] = "\27[36m", - ["white"] = "\27[37m", - ["grey"] = "\27[90m", - ["orange"] = "\27[91m", - ["reset"] = "\27[0m" - } - - return colorList[colorId]..message..colorList["reset"] -end - -function logSystem.log(type, message) - local logReactions = { - ["info"] = function(text) - print("["..color("blue","Info").."] "..text) - end, - ["warning"] = function(text) - print("["..color("yellow","Warning").."] "..color("yellow",text)) - end, - ["error"] = function(text) - print(color("red","[Error]").." "..color("red",text)) - end, - ["debug"] = function(text) - if ARGUMENTS and ARGUMENTS.settings.verboseEnabled == true then - print("["..color("grey","Debug").."] "..color("grey",text)) - end - end, - ["switch"] = function (text) - print(color("green","[Output Switch] "..text)) - print("--------------------------") - end, - ["switchEnd"] = function (text) - print("--------------------------") - end, - ["download"] = function (text) - print("["..color("green","Download").."] "..text) - end - } - - if (logReactions[type]) then - logReactions[type](message) - else - error("Unknown log type : "..type) - end -end - -return logSystem diff --git a/modules/systemUtils.lua b/modules/systemUtils.lua deleted file mode 100644 index ac668e6..0000000 --- a/modules/systemUtils.lua +++ /dev/null @@ -1,43 +0,0 @@ --- External Modules -local socket = require("socket") - --- Custom modules -local logSystem = require("modules.logSystem") - --- Module -local systemUtils = {} - -function systemUtils.checkPlatform() - if (os.execute("uname -m | grep 'x86_64' > /dev/null 2>&1") == true) then - return "x64" - elseif (os.execute("uname -m | grep 'x86' > /dev/null 2>&1") == true) then - return "x86" - elseif (os.execute("uname -m | grep 'aarch64' > /dev/null 2>&1") == true) then - return "arm64" - elseif (os.execute("uname -m | grep 'arm' > /dev/null 2>&1") == true) then - return "arm" - else - logSystem.log("error", "Could not determine processor platform... Can't use local install method.") - return nil - end -end - -function systemUtils.isInternetAvailable() - local host = "1.1.1.1" - local port = 53 - - local client = socket.udp() - client:settimeout(5) - local result, err = client:sendto("", host, port) - client:close() - - if result then - logSystem.log("debug", "Internet connection is available.") - return true - else - logSystem.log("error", "Internet connection is not available. Error : "..err) - return false - end -end - -return systemUtils diff --git a/rokit.toml b/rokit.toml new file mode 100644 index 0000000..f98c9ba --- /dev/null +++ b/rokit.toml @@ -0,0 +1,10 @@ +# This file lists tools managed by Rokit, a toolchain manager for Roblox projects. +# For more information, see https://github.com/rojo-rbx/rokit + +# New tools can be added by running `rokit add ` in a terminal. + +[tools] +lune = "lune-org/lune@0.8.8" +darklua = "seaofvoices/darklua@0.13.1" +selene = "Kampfkarren/selene@0.27.1" +StyLua = "JohnnyMorganz/StyLua@0.20.0" diff --git a/selene.toml b/selene.toml new file mode 100644 index 0000000..49bce28 --- /dev/null +++ b/selene.toml @@ -0,0 +1,2 @@ +std = "luau" +exclude = ["luneTypes.d.luau"] diff --git a/smf b/smf deleted file mode 100755 index 70c2a4f..0000000 --- a/smf +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh - -# Check if installed locally (smf.lua is in the same directory as this script) or in the system (smf.lua is in /usr/share/stomp-my-files) -if [ -f "$(dirname $0)/smf.lua" ]; then - # Installed locally - SCRIPT_PATH="$(dirname $0)" -elif [ -f "/usr/share/stomp-my-files/smf.lua" ]; then - # Installed in the system - SCRIPT_PATH="/usr/share/stomp-my-files" -else - echo "smf.lua not found. Please install StompMyFiles and try again." - exit 1 -fi - -# Set LUA_PATH to avoid missing require issues, using the detected directory -export LUA_PATH="$SCRIPT_PATH/?.lua;$SCRIPT_PATH/?/init.lua;;" - -# Check if Lua is installed and run smf.lua, accounting for the script path -if [ -x "$(command -v lua)" ]; then - lua $SCRIPT_PATH/smf.lua "$@" -else - echo "No Lua installation found. Please install Lua and try again." - exit 1 -fi diff --git a/smf.lua b/smf.lua deleted file mode 100644 index 87321dd..0000000 --- a/smf.lua +++ /dev/null @@ -1,152 +0,0 @@ --- Program Data -require("extra.programMetadata") -- Constants used throughout the program. - --- Compression Tools -local compressors = { - -- Common but strong compressors - ["7z"] = require("compressors.7z"), - ["xz"] = require("compressors.xz"), - - -- Less common, but advantaged when used right. - -- ["upx"] = require("compressors.upx"), - ["dolphin-tool"] = require("compressors.dolphin-tool") - -- ["nsz"] = require("compressors.nsz") -} -local bannedExtensions = require("extra.bannedExtensions") - --- External Modules -local lfs = require("lfs") - --- Custom Modules -local fsUtils = require("modules.fsUtils") -local logSystem = require("modules.logSystem") - --- Now we can start listening to the user. -ARGUMENTS = require("modules.argumentManager") - --- Variables -local filesSkipped = 0 -local checkedCompressors = {} - --- Cache folder -if (not fsUtils.exists(CACHE_FOLDER)) then - logSystem.log("debug", "Creating stomp-my-files folder in cache...") - lfs.mkdir(CACHE_FOLDER) -end - --- Checks -local function checkForCompressor(compressorType) - -- If the compressor wasn't already checked - if (not checkedCompressors[compressorType]) then - -- We check it through its provided function, and if we succeed, it's added to the list. - checkedCompressors[compressorType] = compressors[compressorType].check() - end - -- We return its status. - return checkedCompressors[compressorType] -end - -local function attemptOperation(name, type, input) - local availability = checkForCompressor(name) - if (availability == "system" or availability == "local" or availability == "notDefined") then - if type == "compress" then - return compressors[name].compress(input) - elseif type == "decompress" then - return compressors[name].decompress(input) - else - error("Unknown operation type "..type..".") - end - else - logSystem.log("warning", "Could not provide "..name.." for \""..input.."\". Skipping...") - filesSkipped = filesSkipped + 1 - return "failed" - end -end - ---[[ - MAIN PROGRAM -]] -logSystem.log("debug", "Beginning main function...") - -for _,input in ipairs(ARGUMENTS.toBeCompressed) do - -- We get rid of the possibly present unnecessary / character on folders. - if (input:sub(-1) == "/") then - input = input:sub(1,-2) - end - - if (fsUtils.isDirectory(input)) then - logSystem.log("debug", "File "..input.." is a directory. Using 7z...") - - -- For now, we only use 7z for folders. - if (not attemptOperation("7z", "compress", input)) then - filesSkipped = filesSkipped + 1 - end - else - -- The extension is our current way to determine which tool to use. - local extension = fsUtils.getExtension(input) - if extension == nil then - logSystem.log("info", "File "..input.." has no extension. Assuming it's a compiled executable...") - else - logSystem.log("debug", "File "..input.." uses extension "..extension.." .") - end - - -- We check the file isn't banned. - if (bannedExtensions[extension]) then - logSystem.log("warning", "File "..input.." will not compress well. Skipping...") - filesSkipped = filesSkipped + 1 - break - end - - -- We use a switch to determine which compressor to use. - local switch = { - ["7z"] = function() - attemptOperation("7z", "decompress", input) - end, - ["xz"] = function() - attemptOperation("xz", "decompress", input) - end, - ["iso"] = function() - if ARGUMENTS.settings.isoMode == "wii_gc" then - attemptOperation("dolphin-tool", "compress", input) - elseif ARGUMENTS.settings.isoMode == "iso" then - attemptOperation("xz", "compress", input) - else - logSystem.log("warning", "No behavior specified for ISOs. Skipping...") - filesSkipped = filesSkipped + 1 - end - end, - ["rvz"] = function() - attemptOperation("dolphin-tool", "decompress", input) - end - } - local f = switch[extension] - if (f) then - f() - else - -- We rely on xz as a fallback to unsupported extensions. - if extension ~= nil then - logSystem.log( - "debug", - "No particular behavior defined for "..extension..". Relying on default compression behavior..." - ) - else - logSystem.log( - "debug", - "No particular behavior defined for files without extension (yet). Relying on default compression behavior..." - ) - end - attemptOperation("xz", "compress", input) - end - end -end - --- End of program routine - -if (filesSkipped ~= 0) then - if (filesSkipped == #ARGUMENTS.toBeCompressed) then - logSystem.log("warning", "ATTENTION ! All files/folders were skipped.") - else - logSystem.log("warning", "ATTENTION ! One or more files/folders were skipped.") - end -end - -logSystem.log("info", "Exiting StompMyFiles...") diff --git a/src/Classes/Tool.luau b/src/Classes/Tool.luau new file mode 100644 index 0000000..41d97f0 --- /dev/null +++ b/src/Classes/Tool.luau @@ -0,0 +1,16 @@ +local Console = require('@Utilities/Console') + +local Tool = {} +Tool.metatable = { + __index = Tool, +} + +function Tool.new(name: string, compress: (string) -> (), decompress: (string) -> ()) + return setmetatable({ + name = name, + compress = compress, + decompress = decompress, + }, Tool.metatable) +end + +return Tool diff --git a/src/Metadata/BannedExtensions.luau b/src/Metadata/BannedExtensions.luau new file mode 100644 index 0000000..edd1e58 --- /dev/null +++ b/src/Metadata/BannedExtensions.luau @@ -0,0 +1,17 @@ +return { + -- Lossy compressed picture formats + 'jpg', + 'jpeg', + + -- Lossy compressed audio formats + 'mp3', + 'opus', + 'aac', + + -- Unsupported compressed files + 'zip', + 'rar', + 'zstd', + 'gz', + 'bz2', +} diff --git a/src/Metadata/Help.luau b/src/Metadata/Help.luau new file mode 100644 index 0000000..8f9de35 --- /dev/null +++ b/src/Metadata/Help.luau @@ -0,0 +1,15 @@ +local ProgramMetadata = require('@Metadata/Program') + +return ProgramMetadata.name + .. ' Help Page\ +\ +Usage : ' + .. ProgramMetadata.executable + .. ' [OPTIONS]... FILES\ +\ +Arguments :\ + --help : Displays this help page.\ + --version : Displays the version of the program.\ + --ignore-system : Ignore system executables.\ + --wii-gc : Treat ISOs as Wii/GameCube games.\ +' diff --git a/src/Metadata/Program.luau b/src/Metadata/Program.luau new file mode 100644 index 0000000..f1674d3 --- /dev/null +++ b/src/Metadata/Program.luau @@ -0,0 +1,10 @@ +local process = require('@lune/process') + +return { + name = 'StompMyFiles', + executable = 'smf', + version = '1.0.0-dev', + developer = 'JordanViknar', + url = 'https://github.com/JordanViknar/StompMyFiles', + cacheFolder = process.env.HOME .. '/.cache/StompMyFiles/', +} diff --git a/src/Tools/init.luau b/src/Tools/init.luau new file mode 100644 index 0000000..5ca4ec4 --- /dev/null +++ b/src/Tools/init.luau @@ -0,0 +1,5 @@ +return { + sevenz = nil, + xz = nil, + dolphin_tool = nil, +} diff --git a/src/Utilities/Arguments.luau b/src/Utilities/Arguments.luau new file mode 100644 index 0000000..bc99ee2 --- /dev/null +++ b/src/Utilities/Arguments.luau @@ -0,0 +1,94 @@ +local fs = require('@lune/fs') +local process = require('@lune/process') +local stdio = require('@lune/stdio') + +local Console = require('@Utilities/Console') +local Program = require('@Metadata/Program') + +type Setup = { + paths: { string }, + settings: { + ISOHandling: 'Wii/GC' | 'Normal', + ignoreSystemLibs: boolean, + }, +} + +local Arguments = {} + +function Arguments.detect(): Setup + -- Defaults + local ISOHandling: 'Wii/GC' | 'Normal' = 'Normal' + local ignoreSystemLibs: boolean = false + + -- Arguments + local arguments = { + ['--ignore-system'] = function() + ignoreSystemLibs = true + end, + ['--help'] = function() + print(require('@Metadata/Help')) + process.exit(0) + end, + ['--wii-gc'] = function() + Console.separator() + print( + Console.color('red', 'WARNING !') .. '\n' .. + 'StompMyFiles aims for pure brute strength, not performance !\nWii/GameCube games compressed with it may not perform well or malfunction under Dolphin until decompression.' + ) + Console.separator() + if stdio.prompt('confirm', 'Is this what you want ?') then + Console.log('info', 'ISOs will be treated as Wii/GameCube games.') + ISOHandling = 'Wii/GC' + else + process.exit(1) + end + end, + ['--version'] = function() + print( + string.format( + '%s\nUniversal file compression utility, aiming for brute strength and ease of use.message\n(Also useful if you\'re freezing, since it may set your CPU or RAM on fire)\n\n%s\n%s', + Console.color('red', Program.name .. ' version ' .. Program.version), + 'Developped by ' .. Console.color('yellow', Program.developer), + Console.color('blue', Program.url) + ) + ) + process.exit(0) + end, + } + + -- And the argument management + local paths = {} + for _, argument in ipairs(process.args) do + local sequence: () -> () | nil = arguments[argument] + if sequence then + -- Argument exists + sequence() + else + -- Argument doesn't exist, we assume the user is trying to open a file. + if fs.metadata(argument).exists then + if not table.find(paths, argument) then + table.insert(paths, argument) + else + Console.log('info', 'File ' .. argument .. ' is already in the list. Skipping...') + end + else + Console.log('warn', 'File or flag ' .. argument .. ' does not exist. Skipping...') + end + end + end + + if #paths == 0 then + Console.log('error', 'No valid input path specified.') + process.exit(1) + end + + return { + paths = paths, + settings = { + ISOHandling = ISOHandling, + ignoreSystemLibs = ignoreSystemLibs, + }, + } +end + +return Arguments diff --git a/src/Utilities/Console.luau b/src/Utilities/Console.luau new file mode 100644 index 0000000..6d7d37e --- /dev/null +++ b/src/Utilities/Console.luau @@ -0,0 +1,46 @@ +local stdio = require('@lune/stdio') + +type Color = 'black' | 'blue' | 'cyan' | 'green' | 'purple' | 'red' | 'reset' | 'white' | 'yellow' +type LogType = 'info' | 'warn' | 'error' | 'debug' | 'data' | 'speed' | 'special' | 'success' + +local Console = {} + +function Console.color(color: Color, text: string): string + return stdio.color(color) .. text .. stdio.color('reset') +end + +function Console.log(type: LogType, message: string | number) + local time = os.date('%H:%M:%S') + + local logFunctions = { + info = function(text) + print(time .. ' - [' .. Console.color('blue', 'Info') .. '] : ' .. text) + end, + warn = function(text) + print(time .. ' - [' .. Console.color('yellow', 'Warn') .. '] : ' .. Console.color('yellow', text)) + end, + error = function(text) + print(time .. ' - ' .. Console.color('red', '[Error] : ' .. text)) + end, + debug = function(text) + print(time .. ' - [' .. Console.color('white', 'Debug') .. '] : ' .. Console.color('white', text)) + end, + data = function(text) + print(time .. ' - [' .. Console.color('purple', 'Data') .. '] : ' .. text) + end, + speed = function(startTime) + print(time .. ' - [' .. Console.color('white', 'Speed') .. '] : ' .. 'Done in ' .. os.clock() - startTime .. ' seconds.') + end, + success = function(text) + print(time .. ' - [' .. Console.color('green', 'Success') .. '] : ' .. text) + end, + } + + logFunctions[type](message) +end + +function Console.separator() + print('---------------------------------------------------------------') +end + +return Console diff --git a/src/Utilities/Filesystem.luau b/src/Utilities/Filesystem.luau new file mode 100644 index 0000000..336afd8 --- /dev/null +++ b/src/Utilities/Filesystem.luau @@ -0,0 +1,13 @@ +local fs = require('@lune/fs') + +local Filesystem = {} + +function Filesystem.getFileExtension(path: string): string? + return path:match('[^/]+%.([^.]+)$') +end + +function Filesystem.getFileName(path: string): string? + return path:match('([^/]+)$') +end + +return Filesystem diff --git a/src/init.luau b/src/init.luau new file mode 100644 index 0000000..dd0c60b --- /dev/null +++ b/src/init.luau @@ -0,0 +1,91 @@ +local fs = require('@lune/fs') + +local Arguments = require('@Utilities/Arguments') +local BannedExtensions = require('@Metadata/BannedExtensions') +local Console = require('@Utilities/Console') +local Filesystem = require('@Utilities/Filesystem') +local Program = require('@Metadata/Program') +local Tools = require('@Tools/') + +local Application = {} + +function Application.start() + -- Check cache folder + if not fs.metadata(Program.cacheFolder).exists then + Console.log('debug', 'Creating StompMyFiles folder in cache...') + fs.writeDir(Program.cacheFolder) + end + + local setup = Arguments.detect() + + Console.log('debug', 'Beginning main function...') + + local filesSkipped = 0 + + for _, path in ipairs(setup.paths) do + if not Application.handlePath(path) then + filesSkipped += 1 + end + end + + if filesSkipped ~= 0 then + if filesSkipped == #setup.paths then + Console.log('error', 'All files/folders were skipped.') + else + Console.log('warn', 'One or more files/folders were skipped.') + end + end +end + +function Application.handlePath(path: string) : boolean + if fs.isDir(path) then + -- For now, SMF only compresses the folder without recursively travelling it to compress files. + Console.log('debug', 'Path ' .. path .. ' is a directory. Using 7z...') + + return true + elseif fs.isFile(path) then + -- The extension is our current way to determine which tool to use. + local extension = Filesystem.getFileExtension(path) + if extension == nil then + Console.log('info', 'File "' .. path .. '" has no extension. Assuming it\'s a compiled executable...') + else + Console.log('debug', 'File "' .. path .. '" uses extension "' .. extension .. '".') + end + + -- We check the file isn't banned. + if extension and table.find(BannedExtensions, extension) then + Console.log('warn', 'File "' .. path .. '" will not compress well. Skipping...') + return false + end + + -- Using a switch to determine the tool to use. + local switch = { + -- Compress + ['iso'] = nil, + + -- Decompress + ['7z'] = nil, + ['xz'] = nil, + ['rvz'] = nil, + } + local func: ((string) -> (boolean))? = switch[extension] + if func then + return func(path) + else + -- We rely on xz as a fallback to unsupported extensions. + if extension ~= nil then + Console.log('debug', 'No particular behavior defined for "' .. extension .. '". Relying on default compression behavior...') + else + Console.log('debug', 'No particular behavior defined for files without extension (yet). Relying on default compression behavior...') + end + -- Run XZ compression here. + + return false + end + else + Console.log('error', 'Unknown problem with path "' .. path .. '".') + return false + end +end + +return Application diff --git a/stylua.toml b/stylua.toml new file mode 100644 index 0000000..d9dfa45 --- /dev/null +++ b/stylua.toml @@ -0,0 +1,9 @@ +column_width = 160 +line_endings = "Unix" +indent_type = "Tabs" +indent_width = 4 +quote_style = "ForceSingle" +call_parentheses = "Always" + +[sort_requires] +enabled = true From 610d54dc24de24476b0a4f01e8225009b2bea510 Mon Sep 17 00:00:00 2001 From: JordanViknar <74505993+JordanViknar@users.noreply.github.com> Date: Thu, 19 Sep 2024 16:45:30 +0200 Subject: [PATCH 2/5] feat: Re-add XZ support & unfinished dolphin-tool support --- src/Classes/Tool.luau | 55 +++++++++++++++++++++++++------ src/Tools/dolphin-tool.luau | 61 +++++++++++++++++++++++++++++++++++ src/Tools/init.luau | 4 +-- src/Tools/xz.luau | 42 ++++++++++++++++++++++++ src/Utilities/Arguments.luau | 6 ++-- src/Utilities/Console.luau | 5 +++ src/Utilities/Filesystem.luau | 2 -- src/Utilities/System.luau | 25 ++++++++++++++ src/init.luau | 23 +++++++------ 9 files changed, 198 insertions(+), 25 deletions(-) create mode 100644 src/Tools/dolphin-tool.luau create mode 100644 src/Tools/xz.luau create mode 100644 src/Utilities/System.luau diff --git a/src/Classes/Tool.luau b/src/Classes/Tool.luau index 41d97f0..b31fbdb 100644 --- a/src/Classes/Tool.luau +++ b/src/Classes/Tool.luau @@ -1,16 +1,53 @@ local Console = require('@Utilities/Console') +local System = require('@Utilities/System') -local Tool = {} -Tool.metatable = { - __index = Tool, +export type Tool = { + name: string, + executable: string?, + compress: (string) -> (), + decompress: (string) -> (), } -function Tool.new(name: string, compress: (string) -> (), decompress: (string) -> ()) - return setmetatable({ +local Tool = {} +Tool.Interface = {} + +function Tool.Interface.new(name: string, compress: (string, string) -> (), decompress: (string, string) -> ()): Tool + local executable = nil + local function checkForExecutable(): string? + if executable then + return executable + end + + -- Check first if accessible from PATH + if System.isExecutableInPATH(name) then + executable = name + return executable + else + -- Not accessible, must use cache, download, or give up. + -- NOT YET IMPLEMENTED. + return nil + end + end + + return { name = name, - compress = compress, - decompress = decompress, - }, Tool.metatable) + compress = function(path: string) + local exec = checkForExecutable() + if exec then + return compress(exec, path) + else + Console.visibleError('Can\'t find a valid executable for "' .. name .. '".') + end + end, + decompress = function(path: string) + local exec = checkForExecutable() + if exec then + return decompress(exec, path) + else + Console.visibleError('Can\'t find a valid executable for "' .. name .. '".') + end + end, + } end -return Tool +return Tool.Interface diff --git a/src/Tools/dolphin-tool.luau b/src/Tools/dolphin-tool.luau new file mode 100644 index 0000000..fbcf3f8 --- /dev/null +++ b/src/Tools/dolphin-tool.luau @@ -0,0 +1,61 @@ +local process = require('@lune/process') + +local Console = require('@Utilities/Console') +local Filesystem = require('@Utilities/Filesystem') +local System = require('@Utilities/System') +local Tool = require('@Classes/Tool') + +-- Variables +local allowedRAM = math.floor((System.getRAM() / 1024) * 0.6) + +-- Properties + +local name = 'dolphin-tool' + +local function compress(executable: string, file: string) + Console.log('info', 'Compressing ' .. file .. ' using "' .. executable .. '".') + Console.visibleError('Unimplemented...') + + local dolphin_tool = process.spawn(executable, { + 'convert', + '-f', + 'rvz', + '-c', + 'lzma2', + '-l', + '9', + '-b', + '2097152', + '-i', + file, + '-o', -- Unfinished + }) + + if dolphin_tool.ok then + print(dolphin_tool.stdout) + else + Console.visibleError('"dolphin-tool" encountered an error : ' .. dolphin_tool.stderr) + end +end + +local function decompress(executable: string, file: string) + Console.log('info', 'Decompressing ' .. file .. ' using "' .. executable .. '".') + Console.visibleError('Unimplemented...') + + local dolphin_tool = process.spawn(executable, { + 'convert', + '-f', + 'iso', + '-i', + file, + '-o', -- Unfinished + }) + + if dolphin_tool.ok then + print(dolphin_tool.stdout) + else + Console.visibleError('"dolphin-tool" encountered an error : ' .. dolphin_tool.stderr) + end +end + +return Tool.new(name, compress, decompress) diff --git a/src/Tools/init.luau b/src/Tools/init.luau index 5ca4ec4..3f03293 100644 --- a/src/Tools/init.luau +++ b/src/Tools/init.luau @@ -1,5 +1,5 @@ return { sevenz = nil, - xz = nil, - dolphin_tool = nil, + xz = require('xz'), + dolphin_tool = require('dolphin-tool'), } diff --git a/src/Tools/xz.luau b/src/Tools/xz.luau new file mode 100644 index 0000000..743b4e3 --- /dev/null +++ b/src/Tools/xz.luau @@ -0,0 +1,42 @@ +local process = require('@lune/process') + +local Console = require('@Utilities/Console') +local System = require('@Utilities/System') +local Tool = require('@Classes/Tool') + +-- Variables +local allowedRAM = math.floor((System.getRAM() / 1024) * 0.6) + +-- Properties + +local name = 'xz' + +local function compress(executable: string, file: string) + Console.log('info', 'Compressing ' .. file .. ' using "' .. executable .. '" with ' .. allowedRAM .. 'GB of RAM.') + local xz = process.spawn(executable, { + '-z9e', + '--threads=0', + '--memlimit=' .. allowedRAM .. 'GB', + file, + }) + + if not xz.ok then + Console.visibleError('"xz" encountered an error : ' .. xz.stderr) + end +end + +local function decompress(executable: string, file: string) + Console.log('info', 'Decompressing ' .. file .. ' using "' .. executable .. '" with ' .. allowedRAM .. 'GB of RAM.') + local xz = process.spawn(executable, { + '-d', + '--threads=0', + '--memlimit=' .. allowedRAM .. 'GB', + file, + }) + + if not xz.ok then + Console.visibleError('"xz" encountered an error : ' .. xz.stderr) + end +end + +return Tool.new(name, compress, decompress) diff --git a/src/Utilities/Arguments.luau b/src/Utilities/Arguments.luau index bc99ee2..a4d328e 100644 --- a/src/Utilities/Arguments.luau +++ b/src/Utilities/Arguments.luau @@ -5,7 +5,7 @@ local stdio = require('@lune/stdio') local Console = require('@Utilities/Console') local Program = require('@Metadata/Program') -type Setup = { +export type Setup = { paths: { string }, settings: { ISOHandling: 'Wii/GC' | 'Normal', @@ -32,8 +32,8 @@ function Arguments.detect(): Setup ['--wii-gc'] = function() Console.separator() print( - Console.color('red', 'WARNING !') .. '\n' .. - 'StompMyFiles aims for pure brute strength, not performance !\nWii/GameCube games compressed with it may not perform well or malfunction under Dolphin until decompression.' + Console.color('red', 'WARNING !\n') + .. 'StompMyFiles aims for pure brute strength, not performance !\nWii/GameCube games compressed with it may not perform well or malfunction under Dolphin until decompression.' ) Console.separator() if stdio.prompt('confirm', 'Is this what you want ?') then diff --git a/src/Utilities/Console.luau b/src/Utilities/Console.luau index 6d7d37e..63eef03 100644 --- a/src/Utilities/Console.luau +++ b/src/Utilities/Console.luau @@ -43,4 +43,9 @@ function Console.separator() print('---------------------------------------------------------------') end +function Console.visibleError(text: string): any + Console.log('error', text) + error(text) +end + return Console diff --git a/src/Utilities/Filesystem.luau b/src/Utilities/Filesystem.luau index 336afd8..1cbfe73 100644 --- a/src/Utilities/Filesystem.luau +++ b/src/Utilities/Filesystem.luau @@ -1,5 +1,3 @@ -local fs = require('@lune/fs') - local Filesystem = {} function Filesystem.getFileExtension(path: string): string? diff --git a/src/Utilities/System.luau b/src/Utilities/System.luau new file mode 100644 index 0000000..a272688 --- /dev/null +++ b/src/Utilities/System.luau @@ -0,0 +1,25 @@ +local process = require('@lune/process') + +local Console = require('@Utilities/Console') + +local System = {} + +function System.getRAM(): number + local free = process.spawn('free', { '-m' }) + if free.ok then + local ram = tonumber(free.stdout:match('Mem:%s+(%d+)')) + if ram then + return ram + else + return Console.visibleError('"free -m" process couldn\'t be parsed for RAM count.') + end + else + return Console.visibleError('"free -m" process failed : ' .. free.stderr) + end +end + +function System.isExecutableInPATH(executable: string): boolean + return process.spawn('which', { executable }).ok +end + +return System diff --git a/src/init.luau b/src/init.luau index dd0c60b..d321d4a 100644 --- a/src/init.luau +++ b/src/init.luau @@ -23,7 +23,7 @@ function Application.start() local filesSkipped = 0 for _, path in ipairs(setup.paths) do - if not Application.handlePath(path) then + if not Application.handlePath(path, setup) then filesSkipped += 1 end end @@ -37,7 +37,7 @@ function Application.start() end end -function Application.handlePath(path: string) : boolean +function Application.handlePath(path: string, setup: Arguments.Setup): boolean if fs.isDir(path) then -- For now, SMF only compresses the folder without recursively travelling it to compress files. Console.log('debug', 'Path ' .. path .. ' is a directory. Using 7z...') @@ -61,16 +61,22 @@ function Application.handlePath(path: string) : boolean -- Using a switch to determine the tool to use. local switch = { -- Compress - ['iso'] = nil, + ['iso'] = function(file: string) + if setup.settings.ISOHandling == 'Wii/GC' then + Tools.dolphin_tool.compress(file) + else + Tools.xz.compress(file) + end + end, -- Decompress ['7z'] = nil, - ['xz'] = nil, - ['rvz'] = nil, + ['xz'] = Tools.xz.decompress, + ['rvz'] = Tools.dolphin_tool.decompress, } - local func: ((string) -> (boolean))? = switch[extension] + local func: ((string) -> boolean)? = switch[extension] if func then - return func(path) + return pcall(func, path) else -- We rely on xz as a fallback to unsupported extensions. if extension ~= nil then @@ -78,9 +84,8 @@ function Application.handlePath(path: string) : boolean else Console.log('debug', 'No particular behavior defined for files without extension (yet). Relying on default compression behavior...') end - -- Run XZ compression here. - return false + return pcall(Tools.xz.compress, path) end else Console.log('error', 'Unknown problem with path "' .. path .. '".') From c9ea1fdc003268d1562c6f8991ecee1ec8d922cf Mon Sep 17 00:00:00 2001 From: JordanViknar <74505993+JordanViknar@users.noreply.github.com> Date: Thu, 19 Sep 2024 17:29:50 +0200 Subject: [PATCH 3/5] feat: Finish dolphin-tool support --- src/Tools/dolphin-tool.luau | 21 +++++++++------------ src/Tools/xz.luau | 5 +++-- src/Utilities/Filesystem.luau | 9 +++++++++ 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/Tools/dolphin-tool.luau b/src/Tools/dolphin-tool.luau index fbcf3f8..ffbf226 100644 --- a/src/Tools/dolphin-tool.luau +++ b/src/Tools/dolphin-tool.luau @@ -1,20 +1,16 @@ +local fs = require('@lune/fs') local process = require('@lune/process') local Console = require('@Utilities/Console') local Filesystem = require('@Utilities/Filesystem') -local System = require('@Utilities/System') local Tool = require('@Classes/Tool') --- Variables -local allowedRAM = math.floor((System.getRAM() / 1024) * 0.6) - -- Properties local name = 'dolphin-tool' local function compress(executable: string, file: string) - Console.log('info', 'Compressing ' .. file .. ' using "' .. executable .. '".') - Console.visibleError('Unimplemented...') + Console.log('info', 'Compressing "' .. file .. '" using "' .. executable .. '".') local dolphin_tool = process.spawn(executable, { 'convert', @@ -28,19 +24,19 @@ local function compress(executable: string, file: string) '2097152', '-i', file, - '-o', -- Unfinished + '-o', + (Filesystem.stripExtension(file) or file) .. '.rvz', }) if dolphin_tool.ok then - print(dolphin_tool.stdout) + fs.removeFile(file) else Console.visibleError('"dolphin-tool" encountered an error : ' .. dolphin_tool.stderr) end end local function decompress(executable: string, file: string) - Console.log('info', 'Decompressing ' .. file .. ' using "' .. executable .. '".') - Console.visibleError('Unimplemented...') + Console.log('info', 'Decompressing "' .. file .. '" using "' .. executable .. '".') local dolphin_tool = process.spawn(executable, { 'convert', @@ -48,11 +44,12 @@ local function decompress(executable: string, file: string) 'iso', '-i', file, - '-o', -- Unfinished + '-o', + (Filesystem.stripExtension(file) or file) .. '.iso', }) if dolphin_tool.ok then - print(dolphin_tool.stdout) + fs.removeFile(file) else Console.visibleError('"dolphin-tool" encountered an error : ' .. dolphin_tool.stderr) end diff --git a/src/Tools/xz.luau b/src/Tools/xz.luau index 743b4e3..bb39962 100644 --- a/src/Tools/xz.luau +++ b/src/Tools/xz.luau @@ -12,7 +12,8 @@ local allowedRAM = math.floor((System.getRAM() / 1024) * 0.6) local name = 'xz' local function compress(executable: string, file: string) - Console.log('info', 'Compressing ' .. file .. ' using "' .. executable .. '" with ' .. allowedRAM .. 'GB of RAM.') + Console.log('info', 'Compressing "' .. file .. '" using "' .. executable .. '" with ' .. allowedRAM .. 'GB of RAM.') + local xz = process.spawn(executable, { '-z9e', '--threads=0', @@ -26,7 +27,7 @@ local function compress(executable: string, file: string) end local function decompress(executable: string, file: string) - Console.log('info', 'Decompressing ' .. file .. ' using "' .. executable .. '" with ' .. allowedRAM .. 'GB of RAM.') + Console.log('info', 'Decompressing "' .. file .. '" using "' .. executable .. '" with ' .. allowedRAM .. 'GB of RAM.') local xz = process.spawn(executable, { '-d', '--threads=0', diff --git a/src/Utilities/Filesystem.luau b/src/Utilities/Filesystem.luau index 1cbfe73..76006fc 100644 --- a/src/Utilities/Filesystem.luau +++ b/src/Utilities/Filesystem.luau @@ -8,4 +8,13 @@ function Filesystem.getFileName(path: string): string? return path:match('([^/]+)$') end +function Filesystem.stripExtension(path: string): string? + local dotPosition = path:match('^.*()%.%w+$') + if dotPosition then + return path:sub(1, dotPosition - 1) + else + return nil + end +end + return Filesystem From f22253264d1bb2e751951abd94570199f18d862f Mon Sep 17 00:00:00 2001 From: JordanViknar <74505993+JordanViknar@users.noreply.github.com> Date: Mon, 23 Sep 2024 09:11:58 +0200 Subject: [PATCH 4/5] fix: Temporarily remove "--ignore-system" --- src/Metadata/Help.luau | 2 +- src/Utilities/Arguments.luau | 10 ++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/Metadata/Help.luau b/src/Metadata/Help.luau index 8f9de35..3a0a6e7 100644 --- a/src/Metadata/Help.luau +++ b/src/Metadata/Help.luau @@ -10,6 +10,6 @@ Usage : ' Arguments :\ --help : Displays this help page.\ --version : Displays the version of the program.\ - --ignore-system : Ignore system executables.\ + \ --wii-gc : Treat ISOs as Wii/GameCube games.\ ' diff --git a/src/Utilities/Arguments.luau b/src/Utilities/Arguments.luau index a4d328e..8f9f792 100644 --- a/src/Utilities/Arguments.luau +++ b/src/Utilities/Arguments.luau @@ -8,8 +8,7 @@ local Program = require('@Metadata/Program') export type Setup = { paths: { string }, settings: { - ISOHandling: 'Wii/GC' | 'Normal', - ignoreSystemLibs: boolean, + ISOHandling: 'Wii/GC' | 'Normal' }, } @@ -18,13 +17,9 @@ local Arguments = {} function Arguments.detect(): Setup -- Defaults local ISOHandling: 'Wii/GC' | 'Normal' = 'Normal' - local ignoreSystemLibs: boolean = false -- Arguments local arguments = { - ['--ignore-system'] = function() - ignoreSystemLibs = true - end, ['--help'] = function() print(require('@Metadata/Help')) process.exit(0) @@ -85,8 +80,7 @@ function Arguments.detect(): Setup return { paths = paths, settings = { - ISOHandling = ISOHandling, - ignoreSystemLibs = ignoreSystemLibs, + ISOHandling = ISOHandling }, } end From ea3f8b5139b1a1add56291612586b6cdac8425be Mon Sep 17 00:00:00 2001 From: JordanViknar <74505993+JordanViknar@users.noreply.github.com> Date: Mon, 23 Sep 2024 14:07:55 +0200 Subject: [PATCH 5/5] feat: Restore 7z support --- src/Tools/7z.luau | 40 +++++++++++++++++++++++++++++++++++ src/Tools/init.luau | 2 +- src/Tools/xz.luau | 15 ++----------- src/Utilities/Arguments.luau | 9 ++++++-- src/Utilities/Filesystem.luau | 4 ++++ src/Utilities/System.luau | 24 ++++++++++++--------- src/init.luau | 8 +++---- 7 files changed, 71 insertions(+), 31 deletions(-) create mode 100644 src/Tools/7z.luau diff --git a/src/Tools/7z.luau b/src/Tools/7z.luau new file mode 100644 index 0000000..cccf757 --- /dev/null +++ b/src/Tools/7z.luau @@ -0,0 +1,40 @@ +local fs = require('@lune/fs') + +local Console = require('@Utilities/Console') +local Filesystem = require('@Utilities/Filesystem') +local System = require('@Utilities/System') +local Tool = require('@Classes/Tool') + +-- Properties + +local name = '7z' + +local function compress(executable: string, path: string) + Console.log('debug', 'Getting number of CPU threads for 7z...') + local cores = System.getCoreCount() + Console.log('debug', 'Got ' .. cores .. ' threads.') + + Console.log('info', 'Compressing "' .. path .. '" using 7z with ' .. cores .. ' threads.') + System.runExecutable(executable, { + '-sdel', + '-mx9', + '-ms=on', + '-mmt' .. cores, + 'a', + path .. '.7z', -- Temporary + path, + }) +end + +local function decompress(executable: string, file: string) + Console.log('info', 'Decompressing "' .. file .. '" using 7z.') + System.runExecutable(executable, { + 'x', + file, + '-o' .. (Filesystem.getParent(file) or '.'), + '-sdel', + }) + fs.removeFile(file) +end + +return Tool.new(name, compress, decompress) diff --git a/src/Tools/init.luau b/src/Tools/init.luau index 3f03293..4aad80c 100644 --- a/src/Tools/init.luau +++ b/src/Tools/init.luau @@ -1,5 +1,5 @@ return { - sevenz = nil, + sevenz = require('7z'), xz = require('xz'), dolphin_tool = require('dolphin-tool'), } diff --git a/src/Tools/xz.luau b/src/Tools/xz.luau index bb39962..7be9c17 100644 --- a/src/Tools/xz.luau +++ b/src/Tools/xz.luau @@ -1,5 +1,3 @@ -local process = require('@lune/process') - local Console = require('@Utilities/Console') local System = require('@Utilities/System') local Tool = require('@Classes/Tool') @@ -13,31 +11,22 @@ local name = 'xz' local function compress(executable: string, file: string) Console.log('info', 'Compressing "' .. file .. '" using "' .. executable .. '" with ' .. allowedRAM .. 'GB of RAM.') - - local xz = process.spawn(executable, { + System.runExecutable(executable, { '-z9e', '--threads=0', '--memlimit=' .. allowedRAM .. 'GB', file, }) - - if not xz.ok then - Console.visibleError('"xz" encountered an error : ' .. xz.stderr) - end end local function decompress(executable: string, file: string) Console.log('info', 'Decompressing "' .. file .. '" using "' .. executable .. '" with ' .. allowedRAM .. 'GB of RAM.') - local xz = process.spawn(executable, { + System.runExecutable(executable, { '-d', '--threads=0', '--memlimit=' .. allowedRAM .. 'GB', file, }) - - if not xz.ok then - Console.visibleError('"xz" encountered an error : ' .. xz.stderr) - end end return Tool.new(name, compress, decompress) diff --git a/src/Utilities/Arguments.luau b/src/Utilities/Arguments.luau index 8f9f792..1f6d152 100644 --- a/src/Utilities/Arguments.luau +++ b/src/Utilities/Arguments.luau @@ -8,7 +8,7 @@ local Program = require('@Metadata/Program') export type Setup = { paths: { string }, settings: { - ISOHandling: 'Wii/GC' | 'Normal' + ISOHandling: 'Wii/GC' | 'Normal', }, } @@ -61,6 +61,11 @@ function Arguments.detect(): Setup else -- Argument doesn't exist, we assume the user is trying to open a file. if fs.metadata(argument).exists then + -- Avoid trailing slashes + if fs.isDir(argument) and string.sub(argument, -1) == '/' then + argument = string.sub(argument, 1, -2) + end + if not table.find(paths, argument) then table.insert(paths, argument) else @@ -80,7 +85,7 @@ function Arguments.detect(): Setup return { paths = paths, settings = { - ISOHandling = ISOHandling + ISOHandling = ISOHandling, }, } end diff --git a/src/Utilities/Filesystem.luau b/src/Utilities/Filesystem.luau index 76006fc..b5f5714 100644 --- a/src/Utilities/Filesystem.luau +++ b/src/Utilities/Filesystem.luau @@ -17,4 +17,8 @@ function Filesystem.stripExtension(path: string): string? end end +function Filesystem.getParent(path: string): string? + return path:match('^(.*)/') +end + return Filesystem diff --git a/src/Utilities/System.luau b/src/Utilities/System.luau index a272688..d38e4ab 100644 --- a/src/Utilities/System.luau +++ b/src/Utilities/System.luau @@ -4,22 +4,26 @@ local Console = require('@Utilities/Console') local System = {} -function System.getRAM(): number - local free = process.spawn('free', { '-m' }) - if free.ok then - local ram = tonumber(free.stdout:match('Mem:%s+(%d+)')) - if ram then - return ram - else - return Console.visibleError('"free -m" process couldn\'t be parsed for RAM count.') - end +function System.runExecutable(process_name: string, arguments: { string }?): string + local run = process.spawn(process_name, arguments) + if run.ok then + return run.stdout else - return Console.visibleError('"free -m" process failed : ' .. free.stderr) + return Console.visibleError(string.format('"%s" process failed : %s', process_name .. table.concat(arguments or {}, ' '), run.stderr)) end end +function System.getRAM(): number + return tonumber(System.runExecutable('free', { '-m' }):match('Mem:%s+(%d+)')) + or Console.visibleError('"free -m" process couldn\'t be parsed for RAM count.') +end + function System.isExecutableInPATH(executable: string): boolean return process.spawn('which', { executable }).ok end +function System.getCoreCount(): number + return tonumber(System.runExecutable('nproc')) or Console.visibleError('"nproc" process couldn\'t be parsed for core count.') +end + return System diff --git a/src/init.luau b/src/init.luau index d321d4a..aaa2fb2 100644 --- a/src/init.luau +++ b/src/init.luau @@ -39,10 +39,8 @@ end function Application.handlePath(path: string, setup: Arguments.Setup): boolean if fs.isDir(path) then - -- For now, SMF only compresses the folder without recursively travelling it to compress files. - Console.log('debug', 'Path ' .. path .. ' is a directory. Using 7z...') - - return true + Console.log('debug', 'Path "' .. path .. '" is a directory. Using 7z...') + return pcall(Tools.sevenz.compress, path) elseif fs.isFile(path) then -- The extension is our current way to determine which tool to use. local extension = Filesystem.getFileExtension(path) @@ -70,7 +68,7 @@ function Application.handlePath(path: string, setup: Arguments.Setup): boolean end, -- Decompress - ['7z'] = nil, + ['7z'] = Tools.sevenz.decompress, ['xz'] = Tools.xz.decompress, ['rvz'] = Tools.dolphin_tool.decompress, }