From 26c94eb3db62ec6eebbf8d22c11afe691d9520c4 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Sun, 13 Sep 2026 02:31:32 +0200 Subject: krino: release 0.0.1 — man pages, install, examples, cross and release, README, changelog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also: undo removes the directories its run created; a hardlink is never a duplicate of its own other name; a flag written before "undo" is honoured; --version prints no leading v. Duplicate conditions with different scopes not sharing an original is documented as a known limitation. --- man/krino.1 | 348 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 348 insertions(+) create mode 100644 man/krino.1 (limited to 'man/krino.1') diff --git a/man/krino.1 b/man/krino.1 new file mode 100644 index 0000000..627a2ee --- /dev/null +++ b/man/krino.1 @@ -0,0 +1,348 @@ +.\" SPDX-License-Identifier: GPL-3.0-or-later +.Dd September 13, 2026 +.Dt KRINO 1 +.Os +.Sh NAME +.Nm krino +.Nd sort files in a directory by rules +.Sh SYNOPSIS +.Nm +.Op Fl y | Fl n +.Op Fl v +.Op Fl -json +.Op Fl c Ar file +.Op Ar name ... +.Pp +.Nm +.Cm init +.Pp +.Nm +.Cm new +.Ar name path +.Pp +.Nm +.Cm check +.Op Ar name ... +.Pp +.Nm +.Cm explain +.Ar file +.Pp +.Nm +.Cm log +.Op Fl n Ar count +.Pp +.Nm +.Cm undo +.Op Ar run +.Sh DESCRIPTION +.Nm +sorts the files in one or more configured directories according to rules +kept in +.Xr krino.conf 5 . +For each directory in turn it scans the files, evaluates every rule against +every file, and builds a plan: the chain of actions +.Pq Ic copy , Ic move , Ic rename , Ic delete +that the file's matching rules add up to. +.Pp +Every rule that matches a file adds its actions to that file's chain, in +the order the rules are written; +.Sy (stop) +on a matching rule ends the chain for that file, so a later rule is never +even evaluated against it. +A rule with no actions besides +.Sy (stop) +is an exclusion. +.Pp +Every test sees the file as it was when the directory was scanned: name, +path, size, modification time and content. +Actions already added to a file's chain by an earlier rule never change +what a later rule's tests see, so the whole plan for a directory can be +computed, shown, and approved before anything is touched. +.Pp +With no +.Fl y +or +.Fl n , +.Nm +prints the plan and asks how to proceed +.Pq Sx REVIEW . +.Fl y +applies the plan without asking; +.Fl n +prints it and changes nothing. +If standard input is not a terminal and neither is given, +.Nm +refuses rather than guess. +.Sh OPTIONS +.Bl -tag -width Ds +.It Fl y +Apply the plan without asking. +Cannot be combined with +.Fl n . +.It Fl n +Dry run: print the plan and exit without changing anything. +.It Fl v +Also list files that were skipped as unmatched, ignored or busy, and show +the full reason a test matched or not. +.It Fl -json +With +.Fl n , +print the plan as JSON instead of the table. +Refused unless +.Fl n +is also given. +The document's own +.Ic note +field says its shape is unstable before krino 1.0; a script that reads it +should expect it to change before then. +.It Fl c Ar file +Use +.Ar file +in place of +.Pa $XDG_CONFIG_HOME/krino/krino.conf . +.It Fl h , Fl -help +Print usage and exit. +.It Fl -version +Print +.Dq krino Ar version +and exit. +.El +.Sh SUBCOMMANDS +.Bl -tag -width Ds +.It Ic init +Create the config directory with a commented +.Pa krino.conf +and +.Pa template.conf . +Refuses if +.Pa krino.conf +already exists, and leaves an existing +.Pa template.conf +alone. +.It Ic new Ar name path +Copy +.Pa template.conf +to +.Pa dirs/ Ns Ar name Ns Pa .conf , +fill in +.Ar path , +and append +.Ar name +to +.Ic include +in +.Pa krino.conf , +keeping its comments. +.It Ic check Op Ar name ... +Validate the configuration, list each included directory's rules, and list +which content-extraction tools +.Pq Xr krino.conf 5 , Sx CONTENT EXTRACTION +are available. +With no +.Ar name , +checks every included directory. +.It Ic explain Ar file +Evaluate every rule of +.Ar file Ns 's +directory against it and show each test's result, so a rule that should +match but does not +.Pq or the reverse +can be diagnosed test by test. +See +.Sx KNOWN LIMITATIONS . +.It Ic log Op Fl n Ar count +List the most recent runs, newest first +.Pq Ar count No defaults to 10 : +the run id, its start time, the directories it touched, and what it did. +A run that a later +.Ic undo +has reversed at least one file of is marked +.Pq undone . +.It Ic undo Op Ar run +Reverse +.Ar run . +With no +.Ar run , +reverse the most recent run; if that run is itself an undo, it is refused. +An older run is undone by naming it. +See +.Sx UNDO . +.El +.Sh REVIEW +With neither +.Fl y +nor +.Fl n , +after showing one directory's plan +.Nm +asks: +.Bd -literal -offset indent +[a] apply all [c] choose per file [s] skip this directory [q] quit +.Ed +.Pp +.Ic a +applies every step of every chain shown. +.Ic s +applies nothing in this directory and moves on to the next one. +.Ic q +stops +.Nm +entirely; directories already applied earlier in this run stay applied and +can be reversed with +.Ic undo . +.Pp +.Ic c +asks about each file in turn: +.Bd -literal -offset indent + [y] yes [n] no [a] yes to this and all remaining [d] done, apply chosen so far [q] quit, apply nothing +.Ed +.Pp +Approval is per file: a file's whole chain runs, or none of it. +.Ic d +stops asking and applies whatever was already chosen, declining the rest. +.Ic q +here aborts the review for this directory entirely, discarding even a file +already marked +.Ic yes , +and folds into the top-level +.Ic q +above. +.Sh UNDO +.Ic krino undo +reverses a run's steps, last step first within each file, after building +and showing a plan of its own +.Pq shown and approved the same way as a sort plan; Fl y No and Fl n No apply . +One undo plan covers every directory the run touched, so its menu has no +per-directory skip; +.Ic s +and +.Ic q +both apply nothing: +.Bd -literal -offset indent +[a] apply all [c] choose per file [s] skip [q] quit +.Ed +.Pp +An undo run cannot itself be undone: naming it to +.Ic undo +is refused. +.Pp +A step's reversal is refused when the world has moved on since the step ran +.Pq its target is gone or has changed, or the original path is occupied again ; +a refused file has nothing of its chain reversed, so no file is left half +undone. +An exception is a created directory found non-empty at its own turn: that +alone does not refuse the rest of the file's reversal, since it means +another file still lives there, not that something unexpected changed +underfoot. +Every created directory still empty once every file in the run has had its +turn is then removed, deepest path first, so an undo does not leave the +empty directories it made behind. +.Pp +A permanent delete, +.Sy (delete permanent) , +is never undoable; it is shown in the plan with that reason and nothing is +attempted for it. +.Pp +.Ic krino log +marks a run +.Pq undone +once its undo run has reversed at least one file's chain \(em not that +every file in it was restored: a run left partly reversed, because some +files were declined during the undo's own review, is still shown as +.Pq undone +in full. +.Sh ENVIRONMENT +.Bl -tag -width Ds +.It Ev XDG_CONFIG_HOME +Base of the configuration directory +.Pq Pa $XDG_CONFIG_HOME/krino ; +default +.Pa ~/.config . +.It Ev XDG_STATE_HOME +Base of the log and the per-directory lock files +.Pq Pa $XDG_STATE_HOME/krino ; +default +.Pa ~/.local/state . +.It Ev XDG_DATA_HOME +Base of the trash a +.Sy (delete) +step uses +.Pq Pa $XDG_DATA_HOME/Trash ; +default +.Pa ~/.local/share . +.It Ev PAGER +Used to show a plan taller than the terminal; default +.Dq less -FRX . +Never used for +.Fl -json +output. +.It Ev NO_COLOR +When set, disables the ANSI colour +.Nm +otherwise uses on a terminal for a permanent delete and a refused undo +step. +.El +.Sh FILES +.Bl -tag -width Ds +.It Pa $XDG_CONFIG_HOME/krino/krino.conf +The main configuration file: which directories run, defaults, the log +path. +.It Pa $XDG_CONFIG_HOME/krino/template.conf +Copied by +.Ic krino new +for each new directory. +.It Pa $XDG_CONFIG_HOME/krino/dirs/ Ns Ar name Ns Pa .conf +One file per configured directory. +.It Pa $XDG_STATE_HOME/krino/krino.log +The append-only log every run writes to. +.It Pa $XDG_STATE_HOME/krino/ Ns Ar name Ns Pa .lock +Held for the duration of a run against directory +.Ar name , +so a second +.Nm +against the same directory waits, or fails immediately with +.Fl y . +.It Pa $XDG_DATA_HOME/Trash +The freedesktop.org trash a +.Sy (delete) +step moves files into. +.El +.Sh EXIT STATUS +.Bl -tag -width Ds +.It 0 +Success, including a run that found nothing to do, or one whose plan was +entirely declined at review. +.It 1 +A step failed, a directory's lock was already held by another +.Nm , +or a configured directory could not be read. +.It 2 +A usage mistake or a configuration error. +Flags must come before any directory name on the command line: a flag +found after a directory name is a usage error rather than a guess. +.It 130 +Interrupted +.Pq Ic Ctrl-C +or terminated; the current step, if any, is finished and logged first. +.El +.Sh KNOWN LIMITATIONS +.Ic krino explain +evaluates every test of every rule's condition against the file, without +the cost-ordered short-circuiting a real run uses within an +.Sy and/or . +It can therefore run a content-extraction tool, and report a +.Dq content unreadable +warning, for a test that a real run would never reach because an earlier, +cheaper test in the same condition already decided the rule did not match. +.Ic explain +is a full trace of every test, not a cost-faithful preview of what +.Fl n +would actually spend time on. +.Sh SEE ALSO +.Xr krino.conf 5 +.Pp +.Pa docs/sexp-primer.md +in the source repository +.Pq installed at Pa $PREFIX/share/doc/krino/sexp-primer.md +is a short tutorial on the configuration syntax. -- cgit v1.3