Decouple UI from CLI to reduce size of executable when only the CLI is needed#42
Decouple UI from CLI to reduce size of executable when only the CLI is needed#42philpem wants to merge 20 commits intogeraldholdsworth:mainfrom
Conversation
- Remove unused ExtCtrls and HTTPProtocol dependencies from DiscImage.pas - Add conditional compilation to Utils.pas to exclude GUI code when NO_GUI defined - Create DiscImageContext.pas: shared context for disc image operations - Create CLICommands.pas: standalone CLI command processor without GUI dependencies - Create DiscImageManagerCLI.lpr: CLI-only console application entry point - Create DiscImageManagerCLI.lpi: Lazarus project file for CLI version - Create UtilsCLI.pas: CLI-compatible subset of utility functions This enables building a command-line version of the tool that does not require an X server or GUI toolkits, suitable for headless server use. https://claude.ai/code/session_01H1suvkNPi2MVsX1y9Qy86P
Add -dNO_GUI custom compiler option to all Release build modes (Linux 64-bit, Linux ARM, Windows 64-bit, macOS 64-bit, macOS ARM) so that GUI-dependent code is excluded when building the CLI version. https://claude.ai/code/session_01H1suvkNPi2MVsX1y9Qy86P
TProgressProc is a private type inside TDiscImage class and not accessible from other units. Removed the progress callback functionality from TDiscImageContext as it's not needed for the CLI interface. https://claude.ai/code/session_01H1suvkNPi2MVsX1y9Qy86P
Implement URL percent-encoding/decoding functions locally to replace the dependency on HTTPProtocol unit which was removed for CLI support. https://claude.ai/code/session_01H1suvkNPi2MVsX1y9Qy86P
Rename local variables Free/Used/Total to FreeBytes/UsedBytes/TotalBytes to avoid conflict with the built-in TObject.Free method identifier. https://claude.ai/code/session_01H1suvkNPi2MVsX1y9Qy86P
Renamed local variable 'Params' to 'CmdParams' in DoRun method to avoid shadowing the inherited Params property from TCustomApplication. https://claude.ai/code/session_01H1suvkNPi2MVsX1y9Qy86P
- Deleted UtilsCLI.pas as Utils.pas already has {$IFNDEF NO_GUI}
conditionals that make it work for both GUI and CLI builds
https://claude.ai/code/session_01H1suvkNPi2MVsX1y9Qy86P
Changed build mode names to match DiscImageManager.lpi naming: - "Release Linux 64-bit" → "Release Linux 64 bit" - "Release Linux ARM" → "Release Linux ARM 64 bit" - "Release Windows 64-bit" → "Release Windows 64 bit" - "Release macOS 64-bit" → "Release macOS 64 bit" https://claude.ai/code/session_01H1suvkNPi2MVsX1y9Qy86P
Changed UnitOutputDirectory from lib/ to lib-cli/ to prevent compiled units from conflicting between GUI and CLI builds. https://claude.ai/code/session_01H1suvkNPi2MVsX1y9Qy86P
These are general-purpose string utilities that fit better alongside other string functions in Utils.pas. DiscImage.pas now uses Utils. https://claude.ai/code/session_01H1suvkNPi2MVsX1y9Qy86P
Claude/decouple UI processing p e02f
Add the following commands that were present in the GUI's console mode: - compact/defrag: Defragment disc image partitions - dirtitle: Change current directory title - exec/load/type: Change file addresses and filetypes - find: Search host filesystem (distinct from image search) - filetocsv: Batch CSV export of multiple images - filetype: Translate between filetype names and numbers - interleave: Change ADFS/AFS interleave method - list: Display text/BASIC file contents - report: Show detailed image report - runscript: Execute commands from a script file - savecsv: Save image catalogue as CSV - stamp: Set current timestamp on files - join/split: Placeholders (not implemented in GUI either) Also updated: - cat command output format to match GUI (shows boot option, timestamps, load/exec addresses, filetypes as appropriate for format) - Help text expanded with all commands and format options https://claude.ai/code/session_01H1suvkNPi2MVsX1y9Qy86P
- Remove 'info' command (not in GUI console) - Change 'ls' to behave like GUI: redirects to 'find *' (list host files) instead of being an alias for 'cat' - Remove unused ShowImageInfo procedure - Update help text accordingly https://claude.ai/code/session_01H1suvkNPi2MVsX1y9Qy86P
- CmdDefrag: Mark as not available in CLI mode (requires GUI infrastructure) - CmdList: Convert for-loop to while-loop to fix illegal assignment to loop variable when skipping CR+LF pairs https://claude.ai/code/session_01H1suvkNPi2MVsX1y9Qy86P
The "initial image file" detection used ParamStr(ParamCount) to grab the last command-line argument and try loading it as a disc image. When using `-s FOO.dim`, the script filename FOO.dim is the last argument, so it was incorrectly loaded as a disc image — causing EReadError since a text script file is not a valid disc image. Replace the naive ParamStr(ParamCount) approach with a FindPositionalArg helper that properly walks the argument list, skipping options and their values (-s, -e and their arguments, -n, -h flags), and returns only a true standalone positional argument intended as an image file path. https://claude.ai/code/session_01CctTMMjYE63p4GMLjhrh61
|
Hold off on this one for the moment. The extract command doesn't behave the same as the GUI version: it seems like the GUI recurses while this doesn't. The helpscreen is also wildly different to the original... I'm going to go through and figure out how things differ and bring it back into alignment. We might have to consider this a proof of concept, and I'll go back and do it by hand! |
- Replace hardcoded CLI help text with the same content from GUI's Help.Lines TMemo, using identical formatting (command names in red+bold, descriptions with leading space stripped, word wrapping) - Add recursive directory extraction to CLI extract command via new DownloadFile/DownloadDirectory methods that mirror the GUI's TMainForm.DownLoadFile/DownLoadDirectory behavior - Fix search and extract file accumulation: pass previous results to GetListOfFiles (via Image.FileSearch AddTo parameter) so multiple patterns accumulate rather than overwriting - Add INF file creation support during extraction when CreateINF setting is enabled - Add Global unit import for WrapText function https://claude.ai/code/session_017Xs8rKBbGLsNaa8L8eNMLT
Dir command: - Use ValidFile() instead of FileExists() directly so that relative directory names (e.g. 'Applicatio' while in '$') are resolved by also trying the current-directory-prefixed path (e.g. '$.Applicatio'), matching GUI behavior - Add in-path parent specifier handling (e.g. '$.dir1.^.dir2') matching GUI's ParseCommand dir handler - Properly track Ok state for success/failure reporting Report command: - Use Image.ImageReport(False) to generate the same detailed report as the GUI (disc record, free space map, etc.) - Add file report section with broken directory and CRC error checking, matching GUI's btn_ShowReportClick - Add footer with app title, version, and author info https://claude.ai/code/session_017Xs8rKBbGLsNaa8L8eNMLT
|
I spotted a bug in the original -- if you use the c9a9992 fixes the bug I mentioned above where I've not tested all the commands yet - I only use |
- delete: Add UEF/RFS special handling (entry-based deletion) and
match GUI message format ("X deleted." / "Could not delete X.")
- new: Add AFS, DOS HDD, and Amiga HDD format support
- config: Full 43-option config array with actual get/set via registry,
matching GUI's Configs array exactly
- status: Display all 43 config settings with current values from registry
- add: Support adding directories recursively (matching GUI's combined
add/find handler with exclusion prefix support)
- filetocsv: Implement actual CSV batch output by loading each image
and generating CSV using shared WriteCSVForImage helper
- savecsv: Rewrite to use registry-based CSV preferences (CSVParent,
CSVFilename, CSVLoadAddr, etc.) matching GUI's SaveAsCSV output format
- create: Fix message wording to match GUI ("Create new directory")
- exec/load/type: Add hex validation for type command (matching GUI)
- defrag: Add TODO comment documenting GUI dependency for future work
https://claude.ai/code/session_017Xs8rKBbGLsNaa8L8eNMLT
|
I think the best way to go, particularly for version 2, is to have two separate binaries - one for GUI and the other for console. Both can use the same TDiscImage base class, so therefore code sharing. |
CreateDirectory takes var parameters, so function results can't be passed directly. Assign GetParent() to a local variable first. https://claude.ai/code/session_017Xs8rKBbGLsNaa8L8eNMLT
(My previous PR got deleted because I renamed the branch)
I put this together with Claude AI for a laugh and it turned out to work fairly well.
I've tested it locally and it can list and extract ADFS images from the CLI. The GUI seems to work OK too.
This fixes #39 by introducing a new "DiscImageManagerCLI" project which:
DiscImageContext) to break the dependency on the GUI components.{$IFNDEF NO_GUI}conditionals toUtils.pasto remove the GUI functions in non-GUI builds.It also removes the need for ICS by implementing HTTP URL encoding locally (which is the only thing ICS seems to be used for).
There are now "GUI" and "CLI" builds and never the twain shall meet, as they say.
The CLI code is still in the GUI build, so it's a bit icky. I have another PR to remove that -- we can decide whether or not we want to go that route. Having two executables and no console code in the GUI does mean there's two programs to maintain but it also makes a clear separation of responsibilities. At the moment the GUI mode detection code in the Linux build is broken and always tries to run in console mode (unless overridden with
-gon the command line).