Skip to content

Repository files navigation

Mole

An IDE, but for files.

An editor gives a programmer one window in which to search a project, open several things at once, run tools over them and see the results — without ever reaching for a terminal or a second application. Mole sets out to be that window for files: browsing, searching, comparing, syncing, renaming in bulk, finding duplicates, previewing anything, and running long jobs in the background, all under one keyboard.

It is native and desktop-first, built on C++20 and Qt 6 / QML, and designed from the start so that drives and tabs are both plugin extension points: a tab is one workflow over files, and anything that can list and read entries can be a drive.

Status: early. The architecture is in place and covered by tests; features are being added on top of it.

What works today

  • Virtual drives. Local disk, an in-memory scratch space and read-only archives (zip, tar, 7z, ...) are all mounts of the same IFileSystem interface. Activating an archive mounts it and browses inside.
  • Tabs as workflows. Browser (single pane, dual pane, a grid of icons or a gallery of thumbnails), search, previews, reports and the rest — each a separate feature, opened from the same menu.
  • Filter by typing. Start typing in a listing and it narrows to what you typed — no shortcut, no storage access. A search that walks the tree is a separate tab on Ctrl+F.
  • One search, asked a dozen ways. A name as text, a shape or an expression; a path; a size; dates typed the way people say them (last 7 days, >30d); what a file is rather than what it is called; folders to skip; and the text inside the files themselves. Where to look is a field — this folder, everywhere indexed, or a path — and a query line above the form is the same query seen twice, so report ext:pdf size>10M is the whole of it.
  • Preview with F3. Source code coloured for twenty-odd languages, Markdown rendered, images, video paused at its first frame, CSV/TSV, SQLite databases and Parquet files as a grid with filtering and copyable cells, and the bytes of anything else. What a file is comes from what is in it rather than from its name, so a Dockerfile opens as a coloured Dockerfile. Every viewer has a details panel: a photograph's camera and exposure, a document's author, a video's codecs, an audio file's tags. A file of any size opens at once — only the part being shown is ever read. Left and right step through the folder.
  • Commander-style file operations. Copy and move between panes with F5/F6, across any two drives; rename, create and delete with F2/F7/F8.
  • Dragging in and out. Files leave a listing by pointer into anything that takes files, and arrive the same way into the folder a pane is showing — always as a copy, asking before it overwrites a name. A row that is not on this computer is fetched first, so an archive and a bucket can be dragged out of too.
  • Git state, read and never written. A folder inside a checkout says which branch, how far it is from what it tracks, what the last commit was and how much has changed; the rows carry git's own letters, and a folder says when something inside it has changed. Refreshed when an operation writes or when you commit from the terminal panel. Local drives, and it needs libgit2 — without it Mole behaves exactly as it did before. Mole shows git state and does not change it.
  • Full keyboard control. Arrows, Enter, Insert to select, function keys for operations. Enter hands a file to the desktop's default application.
  • Background everything. Listing, scanning and searching run on a thread pool with progress and cancellation. The UI thread never touches storage.
  • A file index. Scan a tree once, then search it instantly without going back to the disk (or the network). A scan can also record what each file says about itself — a camera, an author, a duration — and list what is inside the archives it meets; the contents themselves are deliberately never indexed. A folder with an indexed subfolder is answered by both at once, and every row says whether it is what is on disk now or what a scan remembered. Re-scans keep what has not changed, and a folder can be put on a clock at any interval. The Indexes tab lists every index there is — how old each one is, what kind of scan built it, whether anything is keeping it fresh — and is where one is rescanned, stopped or thrown away.
  • Thumbnails, and a gallery to put them in. Pictures, PDF first pages and video frames, made off the UI thread, a few at a time, only for what is on screen, and cached in memory and on disk. On a drive that is not local the thumbnail a camera wrote into the file is read instead of the file — kilobytes rather than megabytes — and anything past a ceiling is left alone.
  • Sessions. Open tabs, their folders, their layout and the window's own size come back after a restart. Each tab kind decides what it remembers, plugins included.
  • Drives and bookmarks. The sidebar lists what the machine actually has mounted — with how full each one is, amber past three quarters and red past nine tenths — plus the places you saved yourself. Drives with no meaningful capacity simply show a name.
  • Directory reports. Analyse one folder or several, each with its own history, and diff any run against an earlier one.
  • Jobs on a clock. Put a report on a repeat and it runs in the background, including catching up on a run missed while the machine was off. A tracking tab (Ctrl+Shift+J) shows every attempt and puts failures first.
  • Sync between any two drives. Update, mirror or fill gaps, with filters and a dry run that is the real plan with the last step withheld.
  • Duplicate detection. Four strategies, staged so the expensive comparison only ever sees what the cheap ones could not rule out.
  • Bulk rename. Composable operations with a live preview, and a batch that would collide is refused rather than half-applied.
  • File sets. A hand-built list of files across any number of drives that every operation accepts exactly as it accepts a selection.
  • A terminal panel. A shell for the folder you are looking at, along the bottom of the window.
  • Network drives. SFTP, FTP and FTPS, S3, WebDAV, SMB and NFS, each configured from a short form the backend itself describes. One S3 engine serves AWS, Backblaze B2, MinIO, Ceph, Wasabi and R2 — the endpoint and the addressing style are just fields. A Windows or NAS share and an NFS export are reached in-application, with no mount and no root. They ship as a loadable plugin, and further backends arrive the same way.
  • Credentials encrypted and portable. Passwords live in an AES-256-GCM store keyed by a passphrase you choose, never in the settings file. It is not tied to this machine: back up the configuration and the same passphrase opens it on a fresh install. The encryption is what protects the file at rest on every platform; on Unix it is 0600 as well, and on Windows it is whatever ACL the file inherits from your profile directory, which Qt cannot narrow further.
  • A plugin API with a loadable-shared-library path, used by the shipped archive and network plugins.

Building

Requires a C++20 compiler, CMake 3.24+ and Qt 6.4+.

On Ubuntu 24.04:

sudo apt install -y build-essential ninja-build ccache pkg-config git \
  qt6-base-dev qt6-base-dev-tools qt6-declarative-dev qt6-declarative-dev-tools \
  qt6-tools-dev qt6-tools-dev-tools qt6-svg-dev libqt6sql6-sqlite \
  qml6-module-qtquick qml6-module-qtquick-controls qml6-module-qtquick-layouts \
  qml6-module-qtquick-templates qml6-module-qtquick-window \
  qml6-module-qtqml-workerscript qml6-module-qtquick-shapes \
  libarchive-dev libcurl4-openssl-dev libssl-dev

make build      # binary lands in build/debug/mole
make run
make test

Optional but recommended while developing:

sudo apt install -y clang-format clang-tidy cppcheck valgrind

ccache is optional too, and nothing asks for it: the build looks for it and uses it when it is there. It used to be named in the base preset, which made a machine without it fail to configure at all.

libarchive-dev is optional: without it the archive plugin is skipped and the rest of the application builds normally. The same goes for libcurl4-openssl-dev and libssl-dev, without which the network plugin is skipped and there are no SFTP, FTP, S3 or WebDAV drives — configure says so, rather than offering drives that cannot connect. libsmbclient-dev and libnfs-dev are optional in the same way and one step finer: without either, the plugin still ships and only that drive kind is missing, which configure names.

Getting a binary

make build already produces one at build/debug/mole, but it is a debug build that only runs from the build tree. For anything else:

make optimised   # optimised, still run from build/release/
make install     # into /usr/local — override with PREFIX=~/.local
make bundle      # self-contained folder in dist/, runs without Qt installed
make packages    # a .deb, an .rpm and an AppImage, each for the family it installs on
Download On disk Needs Qt on the target What it cannot do Use it for
make optimised 127 MB yes running on this machine
make install 196 MB yes your own machine
.deb 3.7 MB 10 MB yes, from the archive no Parquet grid Debian and Ubuntu
.rpm 2.5 MB 11 MB yes, from the archive Fedora and RHEL
tarball (make bundle) 79 MB 209 MB no video needs the host's ffmpeg handing it to someone else
AppImage 110 MB 294 MB no no Parquet grid; video needs the host's ffmpeg any distribution from 2021 onwards — it runs on glibc 2.34 and upwards

Where those figures come from, because a size is not a property of the program. Measured on 2026-09-01 from the artefacts the release workflow builds, against Qt 6.4 on Ubuntu 24.04 — except the .rpm, built on Fedora 40, and the AppImage, built on AlmaLinux 9 for the glibc floor (see TODO.md). MB means 10⁶ bytes; on disk is the apparent size of the unpacked tree, which is what your filesystem has to hold. The tarball moved twice on 2026-09-01 and ended smaller than it started: up by about 85 MB when it gained a media backend it had never had, then down by 80 when the whole codec stack was left to the host for the licence reason under Video previews below. The AppImage row is from a build of the same day; it was never carrying the Ubuntu codec closure, so it did not shrink the same way. A build finds what a machine has, so yours will differ: leaving Arrow out takes tens of megabytes off, and the two figures for make optimised and make install are large because neither strips debug information — the packages, the tarball and the AppImage all do.

The AppImage's row carries the one promise that is not about size: it runs on glibc 2.34 — Ubuntu 22.04, Debian 12, RHEL 9 and anything newer — because that is what it was built on, and an AppImage cannot carry the C library it links. Built on something newer it would refuse to start on everything older, with a GLIBC_2.39 not found that reads like a corrupt download. TODO.md records why that floor and not another, and the release checks both ends of it every time.

What it cannot do is the column to read before choosing — and the rule behind that column is the same everywhere: a preview whose library is missing falls back to the file-information view. You get what Mole can say about the file without reading it — its size, type and dates — rather than an error, an empty pane or a crash. mole --plugins says which libraries it found, so a preview that is not what you expected has an answer rather than a guess.

Every artefact browses archives, opens the network drives, renders PDFs, shows git state and keeps its credential store encrypted. The two differences worth knowing about are below, and both are libraries you can install yourself.

The Parquet grid

A .parquet file opens as a grid with filtering and copyable cells where Apache Arrow is available, and as the file-information view where it is not.

libarrow is in no Debian or Ubuntu archive today — not in Debian 12 or 13, not in Ubuntu 24.04 or 25.04 — so the .deb is built without it, and so is the AppImage, whose build host has only Arrow 9 and the code needs newer. Fedora packages Arrow and Parquet, so the .rpm has the grid; the tarball carries its own copy and answers to nobody's archive.

If you want the grid on Debian or Ubuntu, install Arrow from the project's own packages — https://arrow.apache.org/install/ — and use the tarball, which is the artefact built against it. Ubuntu 26.04 carries Arrow 23 in the archive, and from there the .deb can have the grid without anything extra.

Video previews

A video shows a frame from it, and a folder of videos shows a tile for each, where the host has the decoders. Where it has not, both fall back to the file-information view, and mole --plugins says backend found: none that will load.

The tarball and the AppImage deliberately do not carry ffmpeg. A distribution's ffmpeg is built against whatever that distribution is willing to ship, and on Ubuntu that includes libx264, libx265, libxvidcore and libzvbi — GPL-2+ every one — while the AlmaLinux build the AppImage comes from adds libfdk-aac, which is not free software at all. Mole is Apache-2.0, so a self-contained artefact carrying any of them would be one nobody could redistribute. What Mole carries is decided here rather than by somebody's packaging policy, so the whole codec stack is the host's.

Qt's ffmpeg plugin is in both artefacts — it is LGPL, like the rest of Qt. It loads where the host has the libraries and does not where it has not. On any desktop that plays video they are already installed. Where they are not:

Debian, Ubuntu sudo apt install libavcodec60 libavformat60 libswscale7 — or ffmpeg, which pulls all of them
Fedora sudo dnf install ffmpeg-libs (RPM Fusion free)
Arch sudo pacman -S ffmpeg
openSUSE sudo zypper install ffmpeg-4

The Debian sonames move between releases; apt search libavcodec names the one that release has, and installing ffmpeg is the version-proof way. The .deb and .rpm need none of this — they depend on the distribution's own ffmpeg, which arrives with whatever it was built against.

make install lays out <prefix>/bin/mole and <prefix>/lib/mole/plugins, plus a desktop entry and icon so the app shows up in the launcher. The binary finds its plugins relative to itself, so any prefix works without rebuilding.

make bundle additionally copies Qt, the platform plugin, the SQLite driver and the QML modules into dist/, behind a launcher script that points Qt at them. Ship the whole dist/ folder; the entry point is dist/mole.

Check a packaged build without a display:

./dist/mole --plugins    # prints the search path, what loaded, and the media stack
./dist/mole --diagnostics  # the same thing, under the name the code calls it

Checking for new versions

Mole is in no distribution's archive, so nothing updates it for you and nothing would otherwise ever mention that a new version exists. So when it starts, Mole asks once whether it is out of date. That is on by default, and Help → Check for new versions turns it off.

What leaves your machine is one GET of one file:

https://raw.githubusercontent.com/Ogefest/mole/main/latest.json

carrying these headers and nothing else:

Host: raw.githubusercontent.com
User-Agent: Mole
Accept-Language: en
If-None-Match: "<the tag GitHub gave for that file last time>"
Connection: Keep-Alive
Accept-Encoding: <whatever compression your Qt offers>

No install id, no counter, no platform, and no version number. Two of those headers are set by Mole rather than left to Qt, and both for this reason. The user agent says Mole and no more: a version there would be a count of installs per release arriving at somebody else's server. And Accept-Language is fixed at en because Qt builds that header out of your system locale — a default request would say pl-PL,en,* on a Polish machine, which is the one thing in it that says anything about who is asking. If-None-Match is GitHub's own tag for the file from the last time it was read, which is what makes the ordinary answer 304 Not Modified with no body at all. GitHub sees what it sees for any download from the repository, an address and a time; Mole tells it nothing beyond that.

Nothing is downloaded and nothing is installed, ever. Mole names the version and offers to open its release page. Updating is whatever you did to install it.

You are told once per version, and then there is a week of quiet. If a notice is shown and you do nothing, Mole does not ask again — not even the question — for seven days, and a version you have already been told about is never announced a second time.

Failure is silent. No network, a captive portal, a proxy, a firewall, a server error, an answer that stops half way: none of them produces a message, a line in the session log above debug level, or a delay you would notice. A machine that cannot reach GitHub behaves exactly like one that is up to date. MOLE_LOG=update mole says what happened, if you want to know.

Make targets

Target Does
make build configure (if needed) and compile
make run build and launch
make install install into PREFIX (default /usr/local)
make uninstall remove an installed copy
make bundle self-contained folder in dist/
make test build and run the whole suite in parallel
make asan build and test under AddressSanitizer + UBSan + leak detection
make screenshots drive the real interface headlessly and photograph each verified state
make guide-images the same, copied into the user guide
make optimised optimised build with debug info
make release cut a release: all three test tiers, version, changelog marker, commit, tag, push
make format apply .clang-format across the tree
make tidy run clang-tidy over the compilation database
make help list all targets

Without make

The Makefile is a thin wrapper over CMake presets, and it is GNU make with shell recipes — which is not the way in on Windows. Nothing needs porting, because the presets are the real build configuration and CMake drives them directly:

cmake --preset debug          # make build, first half
cmake --build build/debug     # make build, second half
ctest --test-dir build/debug --output-on-failure   # make test

base fixes the generator to Ninja, which exists on all three systems. On Windows that means running these from a developer command prompt, where the MSVC environment has already been set — Ninja finds no compiler otherwise.

Keyboard

Ctrl+T / Ctrl+Shift+T new browser tab / new dual-pane tab
Ctrl+W, Ctrl+Tab, Ctrl+1…9 close, cycle, jump to tab
F4 open the application menu (arrows and Enter from there)
just start typing filter this folder
F3 preview the file under the cursor
Ctrl+F / Ctrl+Shift+I search this folder / search everywhere indexed (new tab)
Ctrl+Shift+C / Ctrl+Shift+F copy this folder's path / the selected file's path
Ctrl+D bookmark this folder — or, in the Sets tab, the set you are looking at
Ctrl+G or Ctrl+L type a destination in the path bar
Ctrl+← / Ctrl+→ / Ctrl+↑ back / forward / up
↑ ↓ PgUp PgDn Home End move the cursor
Enter open — folder, archive as a drive, or the default application
Backspace go up one folder
Tab switch pane (dual mode)
Insert / Space / Ctrl+A / * tick and advance / tick / select all / invert
F2 F5 F6 F7 F8 rename, copy, move, new folder, delete

The button in the toolbar shows the same list in the app.

In the Sets tab the same keys do the same kind of thing to a set's members: the arrows walk them, Enter opens the member itself in a browser with the cursor already on it, and F3 previews it without leaving the set. A member whose file has gone says so rather than opening the folder it used to be in.

The first block works wherever the keyboard is; so do F3 and Ctrl+←/→/↑, because what they act on is the pane in front of you rather than whatever holds the keyboard. The rest need the listing focused — cursor keys, typing to filter and ticking rows are about the thing you are looking at, and F2 F5 F6 F7 F8 need to know which pane they are working from. See ADR-0019.

Layout

src/core       VFS, tasks, event bus, index      (headless, QtCore + QtSql)
src/sdk        the published plugin API
src/host       plugin loader and registries
src/ui         list models and controllers       (headless)
src/plugins    built-in features + archive plugin
src/app        main() and the QML shell
src/tools      mole-tasks, the console runner       (no GUI)
tests          one binary per unit, plus an integration suite
tests/scripts  the shell scripts, run against a stub ssh

Using it

  • docs/guide/ — the user guide: browsing, previewing, searching, and the operations. Every picture in it was taken by the test suite immediately after asserting that what it shows is real, so it cannot document a feature that has stopped working.

From a console

mole-tasks runs any of the work without a window — for reproducing something against a real server, for driving a transfer under tc netem, and for a machine with no display. It reads the same drives, credentials and index the application does. See ADR-0028.

mole-tasks copy --from file:///data/big.bin --to file:///backup --log net
mole-tasks sync --from file:///photos --to nas:///photos --mode mirror   # says what it would do
mole-tasks sync --from file:///photos --to nas:///photos --mode mirror --apply
mole-tasks duplicates file:///downloads --by content
mole-tasks drives                                                        # what is mounted
mole-tasks help                                                          # every command

A drive that needs configuring comes from the store the application writes (--drive «name», with the passphrase in MOLE_PASSPHRASE) or from the command line (--mount name=nas,type=sftp,host=…,user=…,password=@SFTP_PASSWORD). A value written @SOMETHING is read from that environment variable, so a password stays out of the argument list and out of the shell history.

Exit codes: 0 done, 1 something in the work failed, 2 the command line is wrong, 3 a drive could not be reached, 130 interrupted.

Extending it

The extension points:

To add Implement
a drive (SFTP, S3, WebDAV, SMB, NFS, a git forge) IFileSystemFactory + IFileSystem
a tab (duplicates, analytics, bulk rename) IFeature + FeatureController
a viewer (PDF, SQLite, Parquet, bytes) IPreviewProvider + PreviewController
what a file says about itself (EXIF, tags) IMetadataReader
a menu entry under File / View / Tools / Help MenuAction

Built-in functionality is registered through the identical PluginRegistry that third-party code uses, so the API cannot quietly rot.

Environment variables

Variable Effect
MOLE_PLUGIN_PATH extra directories to search for plugins (:-separated)
MOLE_INDEX_PATH where the SQLite index lives, instead of the user profile
MOLE_SESSION_PATH where the open-tabs file lives, instead of the user profile
MOLE_BOOKMARKS_PATH where the bookmarks file lives, instead of the user profile
MOLE_ANALYSIS_PATH where saved reports live, instead of the user profile
MOLE_SCHEDULE_PATH where the job schedule lives, instead of the user profile
MOLE_CHAINS_PATH where saved chains live, instead of the user profile
MOLE_ALERTS_PATH where watched metrics live, instead of the user profile
MOLE_SETS_PATH where file sets live, instead of the user profile
MOLE_SECRETS_PATH where encrypted credentials live, instead of the user profile
MOLE_REMOTES_PATH where configured drives live, instead of the user profile
MOLE_PLUGIN_PATH extra directories to load plugins from
MOLE_LOG_PATH where the session log is written, instead of the user profile
MOLE_STAGING_DIR where a payload is staged while it is written, instead of the temporary directory
MOLE_UPDATE_MANIFEST where to ask what the newest release is, instead of the published manifest
MOLE_LOG what to record in detail: task, drive, net, curl, update, or all
MOLE_PASSPHRASE unlocks the credential store for mole-tasks, which has nobody to ask
MOLE_SCREENSHOT_DIR where tst_Walkthrough writes its pictures

When something goes wrong

Every run writes a session log next to the rest of the profile, keeping the previous run alongside it, and a crash puts its backtrace in the same file. It records what the application said, which for an operation that misbehaved is usually not enough — so MOLE_LOG turns up the detail by subject, into the same file:

MOLE_LOG=net,curl mole      # every network transfer, and libcurl's own account of it
MOLE_LOG=task,drive mole    # what every job did, and every operation on every drive
MOLE_LOG=update mole        # whether it looked for a newer release, and what it decided
MOLE_LOG=all mole           # all of them

task and drive are written in one place each and so cover every job and every drive, including ones a plugin brings. Credentials in header lines are redacted: a log is a thing people send to each other.

Testing the network backends against a real server

The network backends carry conformance tests that talk to an actual server, and they skip themselves when there is nothing to talk to — so make test is green on a machine with no account, and no credential is ever committed. To run them, put an account in the environment:

export MOLE_TEST_SFTP_HOST=… MOLE_TEST_SFTP_USER=… MOLE_TEST_SFTP_PASS=…
export MOLE_TEST_FTP_HOST=…  MOLE_TEST_FTP_USER=…  MOLE_TEST_FTP_PASS=…
export MOLE_TEST_S3_KEY_ID=… MOLE_TEST_S3_SECRET=… MOLE_TEST_S3_BUCKET=…
export MOLE_TEST_S3_REGION=… MOLE_TEST_S3_ENDPOINT=…
export MOLE_TEST_WEBDAV_URL=… MOLE_TEST_WEBDAV_USER=… MOLE_TEST_WEBDAV_PASS=…
make test

One thing to know before running them that way, because the failure does not look like what it is. Those suites run under CTest's 180-second limit like everything else in make test, and a conformance suite against a real server over a real link exceeds it — tst_SftpFileSystem does. What you see is a suite killed part way, which reads as a flaky test rather than as a limit being hit. Raise it for the run:

ctest --test-dir build/debug --timeout 900 -R 'FileSystem' --output-on-failure

or run the suite's binary directly, which is what the project's own live tier does — scripts/testbed/test-live.sh runs each one as its own process for exactly this reason, and reports a suite that skipped as not green, because a suite that never met the server is not a pass.

Each suite works under a uniquely named directory or key prefix and removes it afterwards, so it is safe to point at a bucket or share that holds real files. MOLE_TEST_SFTP_BASE, MOLE_TEST_FTP_BASE and MOLE_TEST_FTP_PORT override where it works and how it connects. Use a throwaway account: these are test credentials in a shell history.

One more of the same shape, and it is a path rather than an account. MOLE_TEST_SNAPSHOT_PATH points at a folder inside a filesystem that exposes its snapshots — set it and tst_LocalSnapshots checks that a real snapshot directory behaves like the ordinary directory the whole feature assumes it is. Everything else about earlier versions is held against a temporary tree in the same shape, so the suite is green on a machine that has never taken a snapshot.

The scale tier

make test-heavy is the same thing at a size that hurts: gigabytes each way, between local disk and every configured backend, with the payload verified byte for byte against what belongs at each offset. It asserts more than "the copy worked" —

  • peak temporary space, which is the check that would have caught staging before it became a wall (see ADR-0014); a copy that streams needs room for a chunk, one that stages needs room for the whole file, and nothing else tells them apart
  • resident memory and file descriptors, so a leak shows up here rather than after eight hours of somebody's backup
  • throughput per run, recorded to a file, so a regression in speed is as visible as one in correctness

It asks the test machine how much room each destination has rather than being told, and a destination that cannot hold the payload is a skip with the reason — filling a test machine's disk would take every other suite down with it. MOLE_TEST_HEAVY_BYTES sets the size; the default is 10 GiB.

The SFTP and S3 suites also carry large-file tests, because that is where transfers break and a few kilobytes prove nothing. SFTP puts 64 MB on the server and reads it back; MOLE_TEST_SFTP_LARGE_MB changes the size, and MOLE_TEST_SFTP_LARGE_PATH points it at a file that is already there, which writes nothing at all. S3 writes an object past the part size so the upload is a multipart one, sized by MOLE_TEST_S3_LARGE_MB.

Roadmap

Backends: SFTP, FTP, S3, WebDAV, SMB and NFS all ship today. Google Drive, Dropbox and OneDrive speak proprietary APIs and would each need a plugin of their own — see ADR-0011. Previews: DuckDB tables. PDF, SQLite, Parquet and video playback are done; so are image metadata and audio tags, which read a header rather than linking exiv2 or taglib — a reader is handed a bounded prefix of a file that may be on a remote drive, and neither library works that way. See ADR-0034.

Cross-platform: Mole is written to be portable, but it has only ever been configured, built and run on Linux. The platform-specific pieces found so far are being worked through; see TODO.md for where that stands.

Licence

Apache-2.0 — see LICENSE.

Qt is used under the LGPL-3.0, dynamically linked and unmodified. Plugins may be released under any licence their author prefers.

make licence-check verifies the conditions that make this combination valid; docs/LICENSING.md explains each one and what you still have to do when publishing a build. Third-party components are listed in THIRD-PARTY-NOTICES.md.

About

No description, website, or topics provided.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages