Skip to content

Commit ce2f395

Browse files
committed
address review: bare 'query' shows help, 'add' subcommand, list previews, SQL hints
- lrc query with no args now prints help (not the stats alias) - promote add to a subcommand: lrc query add <name> "<sql>" (consistent with list/view/delete); removed --add/--name options - lrc query list now shows a truncated SQL preview per alias - on a failed query, append correct-usage examples (alias + raw SQL) - query --help documents the ~/.lrc/queries.toml structure - remove installer queries.toml writing: default aliases are built into the binary, so the installer change was unnecessary LiveReview Pre-Commit Check: skipped (iter:1, coverage:0%)
1 parent f659150 commit ce2f395

5 files changed

Lines changed: 50 additions & 66 deletions

File tree

cmd/app.go

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ type Handlers struct {
6262
RunConfigCheck cli.ActionFunc
6363
RunConfigPreview cli.ActionFunc
6464
RunQuery cli.ActionFunc
65+
RunQueryAdd cli.ActionFunc
6566
RunQueryList cli.ActionFunc
6667
RunQueryView cli.ActionFunc
6768
RunQueryDelete cli.ActionFunc
@@ -370,41 +371,46 @@ TABLE: review_log (one row per commit)
370371
iterations INTEGER review iterations (0 if none)
371372
coverage INTEGER review coverage percent 0-100 (0 if none)
372373
373-
ALIASES: built-ins (stats, by-author, recent) plus your own, saved in
374-
~/.lrc/queries.toml. 'lrc query' with no args runs the 'stats' alias.
374+
ALIASES: built-in (stats, by-author, recent) plus your own. Manage them with
375+
'lrc query add|list|view|delete'. User aliases are saved in ~/.lrc/queries.toml:
376+
377+
[queries]
378+
skipped = "SELECT date, subject FROM review_log WHERE action='skipped'"
379+
my-cov = "SELECT ROUND(AVG(coverage),1) FROM review_log WHERE action='reviewed'"
375380
376381
EXAMPLES
377-
lrc query # default summary (the 'stats' alias)
382+
lrc query stats # run a built-in alias
378383
lrc query stats --json # same data, as JSON
379-
lrc query list # show all aliases
380-
lrc query view stats # show an alias's SQL
384+
lrc query list # show all aliases + a preview
385+
lrc query view stats # show an alias's full SQL
381386
382387
# Was a specific commit reviewed? (incident forensics)
383388
lrc query "SELECT short_hash, action, iterations, coverage FROM review_log WHERE hash LIKE 'a1b2c3%'"
384389
385390
# Per-author review effort
386391
lrc query "SELECT author, COUNT(*) AS commits, SUM(action='reviewed') AS reviewed FROM review_log GROUP BY author ORDER BY commits DESC"
387392
388-
# Coverage only on reviewed commits
389-
lrc query "SELECT ROUND(AVG(coverage),1) AS avg_cov FROM review_log WHERE action='reviewed'"
390-
391393
# Save and reuse your own query
392-
lrc query --add "SELECT date, subject FROM review_log WHERE action='skipped'" --name skipped
394+
lrc query add skipped "SELECT date, subject FROM review_log WHERE action='skipped'"
393395
lrc query skipped --json
394396
395397
# Bound the scan on huge repos (Linux kernel = ~1.5M commits)
396398
lrc query stats --from "2024-01-01" --to "2024-12-31"
397399
lrc query stats --range main...feature # just this PR's commits`,
398400
Flags: []cli.Flag{
399401
&cli.BoolFlag{Name: "json", Usage: "output machine-readable JSON"},
400-
&cli.StringFlag{Name: "add", Usage: "save the given SQL as an alias (requires --name)"},
401-
&cli.StringFlag{Name: "name", Usage: "alias name to save with --add"},
402402
&cli.StringFlag{Name: "from", Usage: "only scan commits since this git date (e.g. 2024-01-01, '2 weeks ago') — bounds large repos"},
403403
&cli.StringFlag{Name: "to", Usage: "only scan commits until this git date"},
404404
&cli.StringFlag{Name: "range", Usage: "only scan a ref range, e.g. main...feature (per-PR stats)"},
405405
},
406406
Action: h.RunQuery,
407407
Subcommands: []*cli.Command{
408+
{
409+
Name: "add",
410+
Usage: "Save a query alias: lrc query add <name> \"<sql>\"",
411+
ArgsUsage: "<name> \"<sql>\"",
412+
Action: h.RunQueryAdd,
413+
},
408414
{
409415
Name: "list",
410416
Usage: "List saved and built-in query aliases",

internal/reviewquery/command.go

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,10 @@ import (
77
"github.com/urfave/cli/v2"
88
)
99

10-
// RunQuery is the default action for `lrc query`. It either saves an alias
11-
// (--add/--name) or runs a saved alias / raw SQL and prints a table or JSON.
10+
// RunQuery is the default action for `lrc query`: runs a saved alias or raw SQL
11+
// and prints a table or JSON. With no argument it shows help (so users discover
12+
// the schema and examples rather than silently running a default query).
1213
func RunQuery(c *cli.Context) error {
13-
if c.IsSet("add") {
14-
add := strings.TrimSpace(c.String("add"))
15-
name := strings.TrimSpace(c.String("name"))
16-
if !c.IsSet("name") || name == "" {
17-
return fmt.Errorf("--add requires --name")
18-
}
19-
if add == "" {
20-
return fmt.Errorf("--add requires non-empty SQL")
21-
}
22-
if err := AddAlias(name, add); err != nil {
23-
return err
24-
}
25-
fmt.Printf("Saved alias %q.\n", name)
26-
return nil
27-
}
28-
2914
// Seed from flags placed BEFORE the positional arg (cli parses those).
3015
jsonOut := c.Bool("json")
3116
filter := Filter{From: c.String("from"), To: c.String("to"), Range: c.String("range")}
@@ -37,11 +22,12 @@ func RunQuery(c *cli.Context) error {
3722
return err
3823
}
3924

40-
arg := "stats" // default alias
41-
if len(positionals) > 0 && strings.TrimSpace(positionals[0]) != "" {
42-
arg = strings.TrimSpace(positionals[0])
25+
// No alias/SQL given -> show help instead of defaulting to a query.
26+
if len(positionals) == 0 || strings.TrimSpace(positionals[0]) == "" {
27+
return cli.ShowSubcommandHelp(c)
4328
}
4429

30+
arg := strings.TrimSpace(positionals[0])
4531
sqlText, found, err := ResolveAlias(arg)
4632
if err != nil {
4733
return err
@@ -53,7 +39,7 @@ func RunQuery(c *cli.Context) error {
5339

5440
res, err := Run(filter, sqlText)
5541
if err != nil {
56-
return err
42+
return fmt.Errorf("%w\n\nRun a saved alias or valid SQL, e.g.:\n lrc query stats\n lrc query \"SELECT * FROM review_log LIMIT 5\"\nSee 'lrc query --help' for the table schema and 'lrc query list' for aliases", err)
5743
}
5844

5945
if jsonOut {
@@ -68,6 +54,29 @@ func RunQuery(c *cli.Context) error {
6854
return nil
6955
}
7056

57+
// RunQueryAdd saves a user alias: `lrc query add <name> "<sql>"`.
58+
func RunQueryAdd(c *cli.Context) error {
59+
name := strings.TrimSpace(c.Args().Get(0))
60+
sqlText := strings.TrimSpace(c.Args().Get(1))
61+
if name == "" || sqlText == "" {
62+
return fmt.Errorf("usage: lrc query add <name> \"<sql>\"")
63+
}
64+
if err := AddAlias(name, sqlText); err != nil {
65+
return err
66+
}
67+
fmt.Printf("Saved alias %q.\n", name)
68+
return nil
69+
}
70+
71+
// truncateSQL shortens a query for compact listing.
72+
func truncateSQL(s string, max int) string {
73+
s = strings.Join(strings.Fields(s), " ") // collapse whitespace/newlines
74+
if len(s) > max {
75+
return s[:max-1] + "…"
76+
}
77+
return s
78+
}
79+
7180
// parseTrailingFlags pulls flags out of args that cli left unparsed (anything
7281
// after the first positional). Supports `--flag value` and `--flag=value`.
7382
// Returns the remaining positional args; sets jsonOut/filter via pointers.
@@ -128,7 +137,7 @@ func RunQueryList(c *cli.Context) error {
128137
return nil
129138
}
130139
for _, a := range aliases {
131-
fmt.Printf("%-18s [%s]\n", a.Name, a.Source)
140+
fmt.Printf("%-16s %-10s %s\n", a.Name, "["+a.Source+"]", truncateSQL(a.SQL, 60))
132141
}
133142
return nil
134143
}

main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ func main() {
8686
RunConfigCheck: appcore.RunConfigCheck,
8787
RunConfigPreview: appcore.RunConfigPreview,
8888
RunQuery: reviewquery.RunQuery,
89+
RunQueryAdd: reviewquery.RunQueryAdd,
8990
RunQueryList: reviewquery.RunQueryList,
9091
RunQueryView: reviewquery.RunQueryView,
9192
RunQueryDelete: reviewquery.RunQueryDelete,

scripts/lrc-install.ps1

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -646,23 +646,6 @@ if (-not $env:HOME -and $env:USERPROFILE) {
646646
$env:HOME = $env:USERPROFILE
647647
}
648648

649-
# Ship default review-history query aliases (idempotent — never clobbers edits)
650-
$LRC_DATA_DIR = Join-Path $env:USERPROFILE ".lrc"
651-
$LRC_QUERIES_FILE = Join-Path $LRC_DATA_DIR "queries.toml"
652-
if (-not (Test-Path $LRC_QUERIES_FILE)) {
653-
New-Item -ItemType Directory -Path $LRC_DATA_DIR -Force | Out-Null
654-
@'
655-
# git-lrc saved queries. Run with: lrc query <name>
656-
# Add your own with: lrc query --add "<sql>" --name "<name>"
657-
# Table columns: hash, short_hash, author, email, date, branch, subject, action, iterations, coverage
658-
[queries]
659-
stats = "SELECT action AS Action, COUNT(*) AS Commits, ROUND(AVG(iterations),1) AS AvgIter, ROUND(AVG(coverage),1) AS AvgCoveragePct FROM review_log GROUP BY action ORDER BY Commits DESC"
660-
by-author = "SELECT author AS Author, COUNT(*) AS Commits, SUM(action = 'reviewed') AS Reviewed FROM review_log GROUP BY author ORDER BY Commits DESC"
661-
recent = "SELECT short_hash AS Hash, date AS Date, action AS Action, subject AS Subject FROM review_log ORDER BY date DESC LIMIT 20"
662-
'@ | Set-Content -Path $LRC_QUERIES_FILE -Encoding UTF8
663-
Write-Host " OK Wrote default query aliases to $LRC_QUERIES_FILE" -ForegroundColor Green
664-
}
665-
666649
# Install global hooks via lrc unless explicitly suppressed by the caller.
667650
if ($LRC_INSTALL_SKIP_HOOKS -eq "1") {
668651
Write-Host "Skipping automatic hook installation because LRC_INSTALL_SKIP_HOOKS=1" -ForegroundColor Yellow

scripts/lrc-install.sh

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -529,21 +529,6 @@ esac
529529
ENVEOF
530530
chmod +x "$LRC_ENV_FILE"
531531

532-
# Ship default review-history query aliases (idempotent — never clobbers edits)
533-
LRC_QUERIES_FILE="$LRC_ENV_DIR/queries.toml"
534-
if [ ! -f "$LRC_QUERIES_FILE" ]; then
535-
cat > "$LRC_QUERIES_FILE" << 'QUERIESEOF'
536-
# git-lrc saved queries. Run with: lrc query <name>
537-
# Add your own with: lrc query --add "<sql>" --name "<name>"
538-
# Table columns: hash, short_hash, author, email, date, branch, subject, action, iterations, coverage
539-
[queries]
540-
stats = "SELECT action AS Action, COUNT(*) AS Commits, ROUND(AVG(iterations),1) AS AvgIter, ROUND(AVG(coverage),1) AS AvgCoveragePct FROM review_log GROUP BY action ORDER BY Commits DESC"
541-
by-author = "SELECT author AS Author, COUNT(*) AS Commits, SUM(action = 'reviewed') AS Reviewed FROM review_log GROUP BY author ORDER BY Commits DESC"
542-
recent = "SELECT short_hash AS Hash, date AS Date, action AS Action, subject AS Subject FROM review_log ORDER BY date DESC LIMIT 20"
543-
QUERIESEOF
544-
echo -e " ${GREEN}OK${NC} Wrote default query aliases to $LRC_QUERIES_FILE"
545-
fi
546-
547532
# Helper: append source line to a shell rc file if not already present
548533
add_source_line() {
549534
local rcfile="$1"

0 commit comments

Comments
 (0)