Compare commits

13 Commits

Author SHA1 Message Date
631843b3c5 Fix installation instructions 2025-12-09 16:15:13 +00:00
9c653e44a4 Fix release badge link 2025-12-09 15:15:19 +00:00
cdd3ba0cbd Merge pull request 'Update README and pyproject.toml' (#23) from update_resrm_20251209 into main
Reviewed-on: #23
2025-12-09 15:13:46 +00:00
eee00bb6ee Edit badges, update installation instructions, swap github.com entries to git.sysmd.uk
All checks were successful
Lint & Security / precommit-and-security (pull_request) Successful in 48s
2025-12-09 15:11:54 +00:00
f9586bbd0e Merge pull request 'Rename .github folder to .gitea. Use pre-commit directly instead of action' (#22) from rename_github_folder into main
Reviewed-on: #22
2025-12-09 13:23:09 +00:00
51a7001bf2 Rename .github folder to .gitea. Use pre-commit directly instead of action
All checks were successful
Lint & Security / precommit-and-security (pull_request) Successful in 47s
2025-12-09 13:19:46 +00:00
ccf383ebfb Remove .coverage and add that to the .gitignore 2025-12-03 11:58:46 +00:00
Marco D'Aleo
6670c79d47 Merge pull request #21 from guardutils/args_list_fix
Fix list flag to use the long name
2025-12-03 11:57:06 +00:00
3285fbaef4 Fix list flag to use the long name 2025-12-03 11:55:15 +00:00
Marco D'Aleo
c07b7598d0 Merge pull request #20 from guardutils/update_resrm_20251202
Tab completion
2025-12-02 18:02:56 +00:00
9edae1d233 Add tab completion using argcomplete, update README 2025-12-02 18:01:17 +00:00
e36ac044d9 Update badges URLs 2025-11-29 16:43:12 +00:00
Marco D'Aleo
1ad635e37e Merge pull request #19 from guardutils/update_resrm_20251127
Switch ownership from mdaleo404 to guardutils in README and pyproject
2025-11-27 17:56:39 +00:00
7 changed files with 112 additions and 32 deletions

View File

@@ -20,7 +20,7 @@ jobs:
run: pip install pre-commit run: pip install pre-commit
- name: Run pre-commit hooks - name: Run pre-commit hooks
uses: pre-commit/action@v3.0.1 run: pre-commit run --all-files --color always
- name: Install pip-audit - name: Install pip-audit
run: pip install pip-audit run: pip install pip-audit

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
__pycache__ __pycache__
.pytest_cache .pytest_cache
dist dist
.coverage

View File

@@ -1,8 +1,6 @@
[![License](https://img.shields.io/github/license/guardutils/resrm?style=flat)](LICENCE) [![Licence](https://img.shields.io/badge/GPL--3.0-orange?label=Licence)](https://git.sysmd.uk/guardutils/resrm/src/branch/main/LICENCE)
[![Language](https://img.shields.io/github/languages/top/guardutils/resrm.svg)](https://github.com/guardutils/resrm/) [![Gitea Release](https://img.shields.io/gitea/v/release/guardutils/resrm?gitea_url=https%3A%2F%2Fgit.sysmd.uk%2F&style=flat&color=orange&logo=gitea)](https://git.sysmd.uk/guardutils/resrm/releases)
![GitHub Release](https://img.shields.io/github/v/release/guardutils/resrm?display_name=release&logo=github) [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-blue?logo=pre-commit&style=flat)](https://git.sysmd.uk/guardutils/resrm/src/branch/main/.pre-commit-config.yaml)
![PyPI - Version](https://img.shields.io/pypi/v/resrm?logo=pypi)
[![PyPI downloads](https://img.shields.io/pypi/dm/resrm.svg)](https://pypi.org/project/resrm/)
# resrm # resrm
@@ -22,34 +20,63 @@ It moves files to a per-user _trash_ instead of permanently deleting them, while
> Note: if you need immediate deletion, use the `--skip-trash` flag. > Note: if you need immediate deletion, use the `--skip-trash` flag.
---
## Configuration
To control how long trashed files are kept, add this line to your shell configuration (e.g. `~/.bashrc`):
```bash
export RESRM_TRASH_LIFE=10
```
---
## Installation ## Installation
### From package manager ### From GuardUtils package repo
This is the preferred method of installation. This is the preferred method of installation.
**Ubuntu 22.04 and 24.04** ### Debian/Ubuntu
#### 1) Import the GPG key
```bash
sudo mkdir -p /usr/share/keyrings
curl -fsSL https://repo.sysmd.uk/guardutils/guardutils.gpg | sudo gpg --dearmor -o /usr/share/keyrings/guardutils.gpg
```
The GPG fingerprint is `0032C71FA6A11EF9567D4434C5C06BD4603C28B1`.
#### 2) Add the APT source
```bash
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/guardutils.gpg] https://repo.sysmd.uk/guardutils/debian stable main" | sudo tee /etc/apt/sources.list.d/guardutils.list
```
#### 3) Update and install
``` ```
sudo add-apt-repository ppa:mdaleo/resrm
sudo apt update sudo apt update
sudo apt install resrm sudo apt install resrm
``` ```
**Fedora 41, 42, 43** ### Fedora/RHEL
#### 1) Import the GPG key
``` ```
sudo dnf copr enable mdaleo/resrm sudo rpm --import https://repo.sysmd.uk/guardutils/guardutils.gpg
```
#### 2) Add the repository configuration
```
sudo tee /etc/yum.repos.d/guardutils.repo > /dev/null << 'EOF'
[guardutils]
name=GuardUtils Repository
baseurl=https://repo.sysmd.uk/guardutils/rpm/$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://repo.sysmd.uk/guardutils/guardutils.gpg
EOF
```
#### 4) Update and install
```
sudo dnf upgrade --refresh
sudo dnf install resrm sudo dnf install resrm
``` ```
@@ -74,7 +101,7 @@ pip install resrm
### From this repository ### From this repository
```bash ```bash
git clone https://github.com/guardutils/resrm.git git clone https://git.sysmd.uk/guardutils/resrm.git
cd resrm/ cd resrm/
poetry install poetry install
``` ```
@@ -107,12 +134,31 @@ resrm --restore <id|name>
resrm --empty resrm --empty
``` ```
## Trash Location ## Trash Location
Normal users: `~/.local/share/resrm/files` Normal users: `~/.local/share/resrm/files`
Root user: `/root/.local/share/resrm/files` Root user: `/root/.local/share/resrm/files`
## Configuration
To control how long trashed files are kept, add this line to your shell configuration (e.g. `~/.bashrc`):
```bash
export RESRM_TRASH_LIFE=10
```
### TAB completion
Add this to your `.bashrc`
```
eval "$(register-python-argcomplete resrm)"
```
And then
```
source ~/.bashrc
```
## pre-commit ## pre-commit
This project uses [**pre-commit**](https://pre-commit.com/) to run automatic formatting and security checks before each commit (Black, Bandit, and various safety checks). This project uses [**pre-commit**](https://pre-commit.com/) to run automatic formatting and security checks before each commit (Black, Bandit, and various safety checks).

16
poetry.lock generated
View File

@@ -1,5 +1,19 @@
# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. # This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand.
[[package]]
name = "argcomplete"
version = "3.6.3"
description = "Bash tab completion for argparse"
optional = false
python-versions = ">=3.8"
files = [
{file = "argcomplete-3.6.3-py3-none-any.whl", hash = "sha256:f5007b3a600ccac5d25bbce33089211dfd49eab4a7718da3f10e3082525a92ce"},
{file = "argcomplete-3.6.3.tar.gz", hash = "sha256:62e8ed4fd6a45864acc8235409461b72c9a28ee785a2011cc5eb78318786c89c"},
]
[package.extras]
test = ["coverage", "mypy", "pexpect", "ruff", "wheel"]
[[package]] [[package]]
name = "cfgv" name = "cfgv"
version = "3.4.0" version = "3.4.0"
@@ -209,4 +223,4 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = ">=3.10,<4.0" python-versions = ">=3.10,<4.0"
content-hash = "140de3164bab6e634d9bd113a3ef763c3d9743a4065ff4fc6b57c17881faa858" content-hash = "7f8ea4efe2d270a676fdd9c882c02f43b4b118bfe7a5fd6da1098ff4ec84ce3d"

View File

@@ -1,16 +1,17 @@
[tool.poetry] [tool.poetry]
name = "resrm" name = "resrm"
version = "0.3.1" version = "0.3.3"
description = "drop-in replacement for rm with undo/restore built-in." description = "drop-in replacement for rm with undo/restore built-in."
authors = ["Marco D'Aleo <marco@marcodaleo.com>"] authors = ["Marco D'Aleo <marco@marcodaleo.com>"]
license = "GPL-3.0-or-later" license = "GPL-3.0-or-later"
readme = "README.md" readme = "README.md"
homepage = "https://github.com/guardutils/resrm" homepage = "https://git.sysmd.uk/guardutils/resrm"
repository = "https://github.com/guardutils/resrm" repository = "https://git.sysmd.uk/guardutils/resrm"
packages = [{include = "resrm", from = "src"}] packages = [{include = "resrm", from = "src"}]
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = ">=3.10,<4.0" python = ">=3.10,<4.0"
argcomplete = ">=2"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
pre-commit = "^3.8" pre-commit = "^3.8"

View File

@@ -8,13 +8,14 @@ Basic usage:
resrm -f file # ignore nonexistent, no prompt resrm -f file # ignore nonexistent, no prompt
resrm -i file # interactive prompt before removal resrm -i file # interactive prompt before removal
resrm --skip-trash file # permanent delete (bypass trash) resrm --skip-trash file # permanent delete (bypass trash)
resrm -l # list trash entries (neat table) resrm -l|--list # list trash entries (neat table)
resrm --restore <id|name> # restore by short-id (8 chars) or exact basename resrm --restore <id|name> # restore by short-id (8 chars) or exact basename
resrm --empty # empty trash entries (permanent) resrm --empty # empty trash entries (permanent)
""" """
from __future__ import annotations from __future__ import annotations
import argparse import argparse
import argcomplete
import json import json
import os import os
import shutil import shutil
@@ -385,13 +386,27 @@ def main(argv: Optional[List[str]] = None):
parser.add_argument( parser.add_argument(
"--skip-trash", action="store_true", help="permanent delete" "--skip-trash", action="store_true", help="permanent delete"
) )
parser.add_argument( restore_arg = parser.add_argument(
"--restore", "--restore",
nargs="+", nargs="+",
metavar="item", metavar="item",
help="restore by id or basename", help="restore by id or basename",
) )
parser.add_argument("-l", action="store_true", help="list trash")
# restore completer
def restore_completer(prefix, parsed_args, **kwargs):
return [
short_id(m["id"])
for m in meta
if short_id(m["id"]).startswith(prefix)
] + [
Path(m["orig_path"]).name
for m in meta
if Path(m["orig_path"]).name.startswith(prefix)
]
restore_arg.completer = restore_completer
parser.add_argument("-l", "--list", action="store_true", help="list trash")
parser.add_argument( parser.add_argument(
"--empty", action="store_true", help="empty the trash permanently" "--empty", action="store_true", help="empty the trash permanently"
) )
@@ -399,6 +414,9 @@ def main(argv: Optional[List[str]] = None):
parser.add_argument( parser.add_argument(
"-V", "--version", action="version", version=f"resrm {get_version()}" "-V", "--version", action="version", version=f"resrm {get_version()}"
) )
argcomplete.autocomplete(parser)
args = parser.parse_args(argv) args = parser.parse_args(argv)
# Always print docstring if -h or --help # Always print docstring if -h or --help
@@ -406,12 +424,12 @@ def main(argv: Optional[List[str]] = None):
print(__doc__) print(__doc__)
return return
if not args.paths and not (args.l or args.empty or args.restore): if not args.paths and not (args.list or args.empty or args.restore):
print("resrm: missing operand") print("resrm: missing operand")
print("Try 'resrm --help' for more information.") print("Try 'resrm --help' for more information.")
return return
if args.l: if args.list:
list_trash() list_trash()
return return