mirror of
https://github.com/PR0M3TH3AN/Marlin.git
synced 2025-09-09 07:38:50 +00:00
update
This commit is contained in:
10
Cargo.lock
generated
10
Cargo.lock
generated
@@ -163,6 +163,15 @@ dependencies = [
|
|||||||
"strsim",
|
"strsim",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_complete"
|
||||||
|
version = "4.5.50"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c91d3baa3bcd889d60e6ef28874126a0b384fd225ab83aa6d8a801c519194ce1"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_derive"
|
name = "clap_derive"
|
||||||
version = "4.5.32"
|
version = "4.5.32"
|
||||||
@@ -374,6 +383,7 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
|
"clap_complete",
|
||||||
"directories",
|
"directories",
|
||||||
"glob",
|
"glob",
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
|
@@ -15,4 +15,4 @@ walkdir = "2.5"
|
|||||||
shlex = "1.3"
|
shlex = "1.3"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
shellexpand = "3.1"
|
shellexpand = "3.1"
|
||||||
|
clap_complete = "4.1"
|
||||||
|
92
README.md
92
README.md
@@ -3,7 +3,7 @@
|
|||||||
# Marlin
|
# Marlin
|
||||||
|
|
||||||
**Marlin** is a lightweight, metadata-driven file indexer that runs 100 % on your computer. It scans folders, stores paths and file stats in SQLite, lets you attach hierarchical **tags** and **custom attributes**, takes automatic snapshots, and offers instant full-text search via FTS5.
|
**Marlin** is a lightweight, metadata-driven file indexer that runs 100 % on your computer. It scans folders, stores paths and file stats in SQLite, lets you attach hierarchical **tags** and **custom attributes**, takes automatic snapshots, and offers instant full-text search via FTS5.
|
||||||
*No cloud, no telemetry – your data never leaves the machine.*
|
_No cloud, no telemetry – your data never leaves the machine._
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
▲ search / exec └──────┬──────┘
|
▲ search / exec └──────┬──────┘
|
||||||
└────────── backup / restore ▼
|
└────────── backup / restore ▼
|
||||||
timestamped snapshots
|
timestamped snapshots
|
||||||
```
|
````
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -51,7 +51,9 @@ macOS & Windows users: let the Rust installer pull the matching build tools.
|
|||||||
git clone https://github.com/yourname/marlin.git
|
git clone https://github.com/yourname/marlin.git
|
||||||
cd marlin
|
cd marlin
|
||||||
cargo build --release
|
cargo build --release
|
||||||
sudo install -Dm755 target/release/marlin /usr/local/bin/marlin # optional
|
|
||||||
|
# (Optional) Install the binary into your PATH:
|
||||||
|
sudo install -Dm755 target/release/marlin /usr/local/bin/marlin
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -61,12 +63,28 @@ sudo install -Dm755 target/release/marlin /usr/local/bin/marlin # optional
|
|||||||
```bash
|
```bash
|
||||||
marlin init # create DB (idempotent)
|
marlin init # create DB (idempotent)
|
||||||
marlin scan ~/Pictures ~/Documents # index files
|
marlin scan ~/Pictures ~/Documents # index files
|
||||||
marlin tag "~/Pictures/**/*.jpg" photos/trip-2024 # add tag
|
marlin tag ~/Pictures/**/*.jpg photos/trip-2024 # add hierarchical tag
|
||||||
marlin attr set "~/Documents/**/*.pdf" reviewed yes
|
marlin attr set ~/Documents/**/*.pdf reviewed yes # set custom attribute
|
||||||
marlin search reviewed --exec "xdg-open {}" # open matches
|
marlin search reviewed --exec "xdg-open {}" # open matches
|
||||||
marlin backup # snapshot DB
|
marlin backup # snapshot DB
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Enable shell completions (optional but handy)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# create the directory if needed
|
||||||
|
mkdir -p ~/.config/bash_completion.d
|
||||||
|
|
||||||
|
# dump Bash completion
|
||||||
|
marlin completions bash > ~/.config/bash_completion.d/marlin
|
||||||
|
```
|
||||||
|
|
||||||
|
For Zsh, Fish, etc., redirect into your shell’s completions folder.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Database location
|
### Database location
|
||||||
|
|
||||||
* **Linux** `~/.local/share/marlin/index.db`
|
* **Linux** `~/.local/share/marlin/index.db`
|
||||||
@@ -89,37 +107,39 @@ marlin <COMMAND> [ARGS]
|
|||||||
init create / migrate database
|
init create / migrate database
|
||||||
scan <PATHS>... walk directories & index files
|
scan <PATHS>... walk directories & index files
|
||||||
tag "<glob>" <tag_path> add hierarchical tag
|
tag "<glob>" <tag_path> add hierarchical tag
|
||||||
attr set|ls … manage custom attributes
|
attr set <pattern> <key> <value> manage custom attributes
|
||||||
search <query> [--exec CMD] FTS query, optionally run CMD on each hit
|
attr ls <path>
|
||||||
|
search <query> [--exec CMD] FTS5 query, optionally run CMD on each hit
|
||||||
backup create timestamped snapshot in backups/
|
backup create timestamped snapshot in backups/
|
||||||
restore <snapshot.db> replace DB with snapshot
|
restore <snapshot.db> replace DB with snapshot
|
||||||
|
completions <shell> generate shell completions
|
||||||
```
|
```
|
||||||
|
|
||||||
### Attribute subcommands
|
### Attribute subcommands
|
||||||
|
|
||||||
| Command | Example |
|
| Command | Example |
|
||||||
| ---------- | ------------------------------------------------ |
|
| ---------- | ---------------------------------------------- |
|
||||||
| `attr set` | `marlin attr set "~/Docs/**/*.pdf" reviewed yes` |
|
| `attr set` | `marlin attr set ~/Docs/**/*.pdf reviewed yes` |
|
||||||
| `attr ls` | `marlin attr ls ~/Docs/report.pdf` |
|
| `attr ls` | `marlin attr ls ~/Docs/report.pdf` |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Backups & restore
|
## Backups & restore
|
||||||
|
|
||||||
*Create snapshot*
|
**Create snapshot**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
marlin backup
|
marlin backup
|
||||||
# → ~/.local/share/marlin/backups/backup_2025-05-14_22-15-30.db
|
# → ~/.local/share/marlin/backups/backup_2025-05-14_22-15-30.db
|
||||||
```
|
```
|
||||||
|
|
||||||
*Restore snapshot*
|
**Restore snapshot**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
marlin restore ~/.local/share/marlin/backups/backup_2025-05-14_22-15-30.db
|
marlin restore ~/.local/share/marlin/backups/backup_2025-05-14_22-15-30.db
|
||||||
```
|
```
|
||||||
|
|
||||||
Marlin also takes an **automatic safety backup before every schema migration**.
|
Marlin also takes an **automatic safety backup before every non-init command**.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -133,40 +153,27 @@ The versioned migration system preserves your data across upgrades.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Roadmap
|
|
||||||
|
|
||||||
See [`ROADMAP.md`](./ROADMAP.md) for the full development plan.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Five-Minute Quickstart
|
## Five-Minute Quickstart
|
||||||
|
|
||||||
Paste & run each block in your terminal.
|
Just paste & run each block in your terminal.
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 0 Prepare, build & install
|
### 0 Prepare, build & install
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd ~/Documents/GitHub/Marlin
|
cd ~/Documents/GitHub/Marlin
|
||||||
cargo build --release
|
cargo build --release
|
||||||
|
|
||||||
sudo install -Dm755 target/release/marlin /usr/local/bin/marlin
|
sudo install -Dm755 target/release/marlin /usr/local/bin/marlin
|
||||||
````
|
```
|
||||||
|
|
||||||
> Now `marlin` is available everywhere.
|
> Now `marlin` is available everywhere.
|
||||||
|
|
||||||
---
|
### 1 Enable shell completion
|
||||||
|
|
||||||
### 1 Enable shell completion (optional but handy)
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
marlin completions bash > ~/.config/bash_completion.d/marlin
|
mkdir -p ~/.config/bash_completion.d
|
||||||
# or for zsh / fish, similarly...
|
marlin completions bash > ~/.config/bash_completion.d/marlin
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2 Prepare a clean demo directory
|
### 2 Prepare a clean demo directory
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -179,8 +186,6 @@ printf "Receipt PDF\n" > ~/marlin_demo/Docs/receipt.pdf
|
|||||||
printf "fake jpg\n" > ~/marlin_demo/Media/Photos/vacation.jpg
|
printf "fake jpg\n" > ~/marlin_demo/Media/Photos/vacation.jpg
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 3 Initialize & index files
|
### 3 Initialize & index files
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -193,23 +198,19 @@ marlin --verbose scan ~/marlin_demo
|
|||||||
|
|
||||||
> Only changed files get re-indexed on subsequent runs.
|
> Only changed files get re-indexed on subsequent runs.
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 4 Attach tags & attributes
|
### 4 Attach tags & attributes
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Tag everything under “Alpha”
|
# Tag everything under “Alpha”
|
||||||
marlin tag "~/marlin_demo/Projects/Alpha/**/*" project/alpha
|
marlin tag ~/marlin_demo/Projects/Alpha/**/* project/alpha
|
||||||
|
|
||||||
# Mark all PDFs as reviewed
|
# Mark all PDFs as reviewed
|
||||||
marlin attr set "~/marlin_demo/**/*.pdf" reviewed=yes
|
marlin attr set ~/marlin_demo/**/*.pdf reviewed yes
|
||||||
|
|
||||||
# Output as JSON instead:
|
# Output as JSON instead:
|
||||||
marlin --format=json attr set "~/marlin_demo/**/*.pdf" reviewed=yes
|
marlin --format=json attr set ~/marlin_demo/**/*.pdf reviewed yes
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 5 Search your index
|
### 5 Search your index
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -223,8 +224,6 @@ marlin search "reviewed AND pdf"
|
|||||||
marlin search reviewed --exec 'echo HIT → {}'
|
marlin search reviewed --exec 'echo HIT → {}'
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 6 Backup & restore
|
### 6 Backup & restore
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -241,8 +240,7 @@ marlin restore "$snap"
|
|||||||
marlin search reviewed
|
marlin search reviewed
|
||||||
```
|
```
|
||||||
|
|
||||||
> Backups live under `~/.local/share/marlin/backups` by default.
|
---
|
||||||
|
|
||||||
|
|
||||||
##### What you just exercised
|
##### What you just exercised
|
||||||
|
|
||||||
@@ -257,9 +255,7 @@ marlin search reviewed
|
|||||||
| `marlin backup` | Timestamped snapshot of the DB |
|
| `marlin backup` | Timestamped snapshot of the DB |
|
||||||
| `marlin restore` | Replace live DB with a chosen snapshot |
|
| `marlin restore` | Replace live DB with a chosen snapshot |
|
||||||
|
|
||||||
That’s the complete surface area of Marlin today—feel free to play around or
|
That’s the complete surface area of Marlin today—feel free to play around or point the scanner at real folders.
|
||||||
point the scanner at real folders.
|
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
23
src/cli.rs
23
src/cli.rs
@@ -9,11 +9,11 @@ pub mod annotate;
|
|||||||
pub mod version;
|
pub mod version;
|
||||||
pub mod event;
|
pub mod event;
|
||||||
|
|
||||||
use clap::{Parser, Subcommand, ArgEnum, Args, CommandFactory};
|
use clap::{Parser, Subcommand, CommandFactory, ValueEnum};
|
||||||
use clap_complete::Shell;
|
use clap_complete::Shell;
|
||||||
|
|
||||||
/// Output format for commands.
|
/// Output format for commands.
|
||||||
#[derive(ArgEnum, Clone, Copy, Debug)]
|
#[derive(ValueEnum, Clone, Copy, Debug)]
|
||||||
pub enum Format {
|
pub enum Format {
|
||||||
Text,
|
Text,
|
||||||
Json,
|
Json,
|
||||||
@@ -78,45 +78,46 @@ pub enum Commands {
|
|||||||
/// Generate shell completions (hidden)
|
/// Generate shell completions (hidden)
|
||||||
#[command(hide = true)]
|
#[command(hide = true)]
|
||||||
Completions {
|
Completions {
|
||||||
|
/// Which shell to generate for
|
||||||
#[arg(value_enum)]
|
#[arg(value_enum)]
|
||||||
shell: Shell,
|
shell: Shell,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// File-to-file links
|
/// File-to-file links
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
Link { cmd: link::LinkCmd },
|
Link(link::LinkCmd),
|
||||||
|
|
||||||
/// Collections (groups) of files
|
/// Collections (groups) of files
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
Coll { cmd: coll::CollCmd },
|
Coll(coll::CollCmd),
|
||||||
|
|
||||||
/// Smart views (saved queries)
|
/// Smart views (saved queries)
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
View { cmd: view::ViewCmd },
|
View(view::ViewCmd),
|
||||||
|
|
||||||
/// Workflow states on files
|
/// Workflow states on files
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
State { cmd: state::StateCmd },
|
State(state::StateCmd),
|
||||||
|
|
||||||
/// TODO/tasks management
|
/// TODO/tasks management
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
Task { cmd: task::TaskCmd },
|
Task(task::TaskCmd),
|
||||||
|
|
||||||
/// Reminders on files
|
/// Reminders on files
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
Remind { cmd: remind::RemindCmd },
|
Remind(remind::RemindCmd),
|
||||||
|
|
||||||
/// File annotations and highlights
|
/// File annotations and highlights
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
Annotate { cmd: annotate::AnnotateCmd },
|
Annotate(annotate::AnnotateCmd),
|
||||||
|
|
||||||
/// Version diffs
|
/// Version diffs
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
Version { cmd: version::VersionCmd },
|
Version(version::VersionCmd),
|
||||||
|
|
||||||
/// Calendar events & timelines
|
/// Calendar events & timelines
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
Event { cmd: event::EventCmd },
|
Event(event::EventCmd),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subcommand, Debug)]
|
#[derive(Subcommand, Debug)]
|
||||||
|
38
src/main.rs
38
src/main.rs
@@ -6,7 +6,7 @@ mod logging;
|
|||||||
mod scan;
|
mod scan;
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand, CommandFactory};
|
||||||
use clap_complete::{generate, Shell};
|
use clap_complete::{generate, Shell};
|
||||||
use glob::Pattern;
|
use glob::Pattern;
|
||||||
use rusqlite::params;
|
use rusqlite::params;
|
||||||
@@ -26,10 +26,11 @@ fn main() -> Result<()> {
|
|||||||
}
|
}
|
||||||
logging::init();
|
logging::init();
|
||||||
|
|
||||||
// Handle shell completions as a hidden command
|
// If the user asked for completions, generate and exit immediately.
|
||||||
if let Commands::Completions { shell } = args.command {
|
if let Commands::Completions { shell } = &args.command {
|
||||||
let mut cmd = Cli::command();
|
let mut cmd = Cli::command();
|
||||||
generate(shell, &mut cmd, "marlin", &mut io::stdout());
|
// Shell is Copy so we can deref it safely
|
||||||
|
generate(*shell, &mut cmd, "marlin", &mut io::stdout());
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,8 +48,11 @@ fn main() -> Result<()> {
|
|||||||
// Open (and migrate) the DB
|
// Open (and migrate) the DB
|
||||||
let mut conn = db::open(&cfg.db_path)?;
|
let mut conn = db::open(&cfg.db_path)?;
|
||||||
|
|
||||||
// Dispatch
|
// Dispatch all commands
|
||||||
match args.command {
|
match args.command {
|
||||||
|
Commands::Completions { .. } => {
|
||||||
|
// no-op, already handled above
|
||||||
|
}
|
||||||
Commands::Init => {
|
Commands::Init => {
|
||||||
info!("Database initialised at {}", cfg.db_path.display());
|
info!("Database initialised at {}", cfg.db_path.display());
|
||||||
}
|
}
|
||||||
@@ -90,15 +94,15 @@ fn main() -> Result<()> {
|
|||||||
info!("Successfully opened restored database.");
|
info!("Successfully opened restored database.");
|
||||||
}
|
}
|
||||||
// new domains delegate to their run() functions
|
// new domains delegate to their run() functions
|
||||||
Commands::Link { cmd } => cli::link::run(&cmd, &mut conn, args.format)?,
|
Commands::Link(link_cmd) => cli::link::run(&link_cmd, &mut conn, args.format)?,
|
||||||
Commands::Coll { cmd } => cli::coll::run(&cmd, &mut conn, args.format)?,
|
Commands::Coll(coll_cmd) => cli::coll::run(&coll_cmd, &mut conn, args.format)?,
|
||||||
Commands::View { cmd } => cli::view::run(&cmd, &mut conn, args.format)?,
|
Commands::View(view_cmd) => cli::view::run(&view_cmd, &mut conn, args.format)?,
|
||||||
Commands::State { cmd } => cli::state::run(&cmd, &mut conn, args.format)?,
|
Commands::State(state_cmd) => cli::state::run(&state_cmd, &mut conn, args.format)?,
|
||||||
Commands::Task { cmd } => cli::task::run(&cmd, &mut conn, args.format)?,
|
Commands::Task(task_cmd) => cli::task::run(&task_cmd, &mut conn, args.format)?,
|
||||||
Commands::Remind { cmd } => cli::remind::run(&cmd, &mut conn, args.format)?,
|
Commands::Remind(rm_cmd) => cli::remind::run(&rm_cmd, &mut conn, args.format)?,
|
||||||
Commands::Annotate { cmd } => cli::annotate::run(&cmd, &mut conn, args.format)?,
|
Commands::Annotate(an_cmd) => cli::annotate::run(&an_cmd, &mut conn, args.format)?,
|
||||||
Commands::Version { cmd } => cli::version::run(&cmd, &mut conn, args.format)?,
|
Commands::Version(v_cmd) => cli::version::run(&v_cmd, &mut conn, args.format)?,
|
||||||
Commands::Event { cmd } => cli::event::run(&cmd, &mut conn, args.format)?,
|
Commands::Event(e_cmd) => cli::event::run(&e_cmd, &mut conn, args.format)?,
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -117,7 +121,11 @@ fn apply_tag(conn: &rusqlite::Connection, pattern: &str, tag_path: &str) -> Resu
|
|||||||
conn.prepare("INSERT OR IGNORE INTO file_tags(file_id, tag_id) VALUES (?1, ?2)")?;
|
conn.prepare("INSERT OR IGNORE INTO file_tags(file_id, tag_id) VALUES (?1, ?2)")?;
|
||||||
|
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
for entry in WalkDir::new(&root).into_iter().filter_map(Result::ok).filter(|e| e.file_type().is_file()) {
|
for entry in WalkDir::new(&root)
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(Result::ok)
|
||||||
|
.filter(|e| e.file_type().is_file())
|
||||||
|
{
|
||||||
let path_str = entry.path().to_string_lossy();
|
let path_str = entry.path().to_string_lossy();
|
||||||
debug!("testing path: {}", path_str);
|
debug!("testing path: {}", path_str);
|
||||||
if !pat.matches(&path_str) {
|
if !pat.matches(&path_str) {
|
||||||
|
Binary file not shown.
@@ -1 +1 @@
|
|||||||
/home/user/Documents/GitHub/Marlin/target/release/marlin: /home/user/Documents/GitHub/Marlin/src/cli.rs /home/user/Documents/GitHub/Marlin/src/config.rs /home/user/Documents/GitHub/Marlin/src/db/migrations/0001_initial_schema.sql /home/user/Documents/GitHub/Marlin/src/db/migrations/0002_update_fts_and_triggers.sql /home/user/Documents/GitHub/Marlin/src/db/mod.rs /home/user/Documents/GitHub/Marlin/src/logging.rs /home/user/Documents/GitHub/Marlin/src/main.rs /home/user/Documents/GitHub/Marlin/src/scan.rs
|
/home/user/Documents/GitHub/Marlin/target/release/marlin: /home/user/Documents/GitHub/Marlin/src/cli/annotate.rs /home/user/Documents/GitHub/Marlin/src/cli/coll.rs /home/user/Documents/GitHub/Marlin/src/cli/event.rs /home/user/Documents/GitHub/Marlin/src/cli/link.rs /home/user/Documents/GitHub/Marlin/src/cli/remind.rs /home/user/Documents/GitHub/Marlin/src/cli/state.rs /home/user/Documents/GitHub/Marlin/src/cli/task.rs /home/user/Documents/GitHub/Marlin/src/cli/version.rs /home/user/Documents/GitHub/Marlin/src/cli/view.rs /home/user/Documents/GitHub/Marlin/src/cli.rs /home/user/Documents/GitHub/Marlin/src/config.rs /home/user/Documents/GitHub/Marlin/src/db/migrations/0001_initial_schema.sql /home/user/Documents/GitHub/Marlin/src/db/migrations/0002_update_fts_and_triggers.sql /home/user/Documents/GitHub/Marlin/src/db/mod.rs /home/user/Documents/GitHub/Marlin/src/logging.rs /home/user/Documents/GitHub/Marlin/src/main.rs /home/user/Documents/GitHub/Marlin/src/scan.rs
|
||||||
|
Reference in New Issue
Block a user