Skip to content

jpmvferreira/stag

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

73 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation


Logo

Stag

Upgrade your hierarchical filesystem with a tag-based structure


Overview

Stag (Simple Tagger) is a FUSE-based filesystem that upgrades your filesystem to support a tag-based structure. It turns tags into folders and remains compatible with a standard Unix utilities and file managers.

Key features are:

  • Tags are Folder: Each tag corresponds to a folder in your filesystem, which stack recursively for files with multiple tags.
  • Files are Files: Each file that you tag will show up in one or more folders, integrating seamlessly with any file manager.
  • Same Tools as Usual: Browse and manage your files the same way you would before, using your favorite file manager or the CLI.

Stag is fully functional, but it's still in alpha, so things might change a bit before the first full release. Once everything settles down, I'll start putting out official versions.

Installation

To run Stag, you need:

You can install Click and fusepy using pip:

$ pip install click fusepy

Make sure FUSE and Python is installed using your system's package manager (e.g., apt, dnf, pacman).

Manual Installation

First, download the Stag script

$ wget https://github.com/jpmvferreira/stag/raw/refs/heads/master/stag

make it executable

$ chmod +x stag

and move it to a directory in your $PATH, e.g.

$ mv stag ~/.local/bin/

If you want Stag to run in the background using Systemd, download the unit file and place it somewhere Systemd can find it

$ wget https://github.com/jpmvferreira/stag/raw/refs/heads/master/stag@.service -O ~/.config/systemd/user/stag@.service
$ systemctl --user daemon-reload

this will allow you to manage Stag mounts easier.

Note

Systemd units do not inherit your user's environment variables, so you may need to change the path to the Stag executable and repository location in the unit file.

Usage

To begin using Stag, first create a repository. For example, to create a repository named myrepo

$ stag init myrepo

Note

Stag assumes the repository is located in ~/.local/share/stag by default. This can be overwritten using the flag -r.

You can list all repositories at any time with

$ stag ls

Stag works by mounting your repository as a virtual filesystem. To do this, create a mount point and mount your repository

$ mkdir mnt
$ stag mount myrepo mnt
$ cd mnt

Tip

If you use the Systemd unit file, you can mount a repository in the background with:

systemctl --user start stag@<name>:<full path>

Systemd will warn you about using /, to avoid issues, replace all / with -, e.g.:

systemctl --user enable now stag@wallpapers:-home-user-wallpapers-

Add files to your repository as you would in any directory, by copying or moving them into the mount point. For demonstration purposes, let's create the following files

$ touch lisbon.txt bern.txt venice.txt

Tags in Stag are represented as directories. To create tags such as city, mountains, and ocean

$ mkdir city ocean mountains

To add a tag to a file, use the ln command. For example, to tag lisbon.txt and venice.txt with city

$ ln lisbon.txt city
$ ln venice.txt city

You can add multiple tags at once, for instance, to tag bern.txt with both city and mountains

$ ln bern.txt city/mountains

If you wish to remove a tag from a file, use rm with the path to the file inside the tag directory

$ rm city/bern.txt

this will remove the tag city from ``bern.txt`, leaving other tags untouched.

It's possible to remove multiple tags at once, e.g., both city and mountains from bern.txt with

$ rm city/mountains/bern.txt

To remove a file entirely from the repository, delete it from the root of the mount point

$ rm bern.txt

To remove a tag from the repository:

$ rmdir mountains

Caution

Do not use rm -r to remove tags, as it will attempt to delete all files within the tag. Always use rmdir to safely remove tags.

It is possible to manage both tags and files using mv. For instance

$ mv <old_tags>/file.txt <new_tags>/file.txt

will remove all tags from file.txt, disregarding <old_tags>, and add <new_tags>.

If you want to rename a file, you must call mv within the same path and change the file name, i.e.

$ mv <tags>/file.txt <tags>/newname.txt

For renaming tags, you can run

$ mv <tags>/<tag> <tags_alt>/<tag_new>

where <tags> and <tags_alt> are ignored and <tag> will be renamed to <tag_new>. If <tag_new> already exists, they will be merged.

Note

To avoid ghost overwrites, Stag does not allow you to change the name of a file to one that already exists. As for tags, it will refuse to change the name to a tag that is not visible in the current subdirectory to avoid ghost merges.

Motivation

Ever you ever started doing some spring cleaning and realized that

$ find wallpapers -type f | wc -l
1603

and, as if this is not bad enough already, you stumbled across

$ find memes -type f | wc -l
1377

Yeah... But, you know what could help you sort all of this mess? That's right: stop hoarding Tags! So I just need to find a program that:

  1. Tags file(s);
  2. Integrates with the filesystem to browse the files and tags;
  3. Uses terminal utilities to interact with files and tags.

As far as I know, there is only one project that comes close to this: TMSU. However, I don't like the folder structure, the CLI is quite complicated and the interaction via filesystem is lacking. It also does more than what I want it to.

Therefore, I decided to make my own version of TMSU, with blackjack smaller codebase and hookers better filesystem integration.

Contributing

This is a small program developed by somebody who is not an experienced programmer. If you have any comments, feedback, suggestions or even feature requests, don't hesitate in opening a ticket or a discussion in this repository.

Disclaimer

Stag is a personal project, not enterprise grade software. I use it myself and it works well for me, but bugs can happen, so don’t trust it with important files unless you’ve got backups (which you should have anyways!). Stag repositories are kept in a single folder, so backing up is very straight forward.

References

The fusepy Github repository, in particular the Python object FUSE implemented in fuse.py.

The official libfuse documentation, mainly the file that defines the operations available in a FUSE filesystem (Data Structures > fuse_operations).

License

MIT

About

Upgrade your hierarchical filesystem with a tag-based structure

Topics

Resources

License

Stars

Watchers

Forks

Languages