refactor(commands): Add IngestDisplay, resolve_project, and color-aware tables
Ingest: - Introduce IngestDisplay struct with show_progress/show_text booleans to decouple progress bars from text output. Replaces the robot_mode bool parameter with explicit display control, enabling sync to show progress without duplicating summary text (progress_only mode). - Use resolve_project() for --project filtering instead of LIKE queries, providing proper error messages for ambiguous or missing projects. List: - Add colored_cell() helper that checks console::colors_enabled() before applying comfy-table foreground colors, bridging the gap between the console and comfy-table crates for --color flag support. - Use resolve_project() for project filtering (exact ID match). - Improve since filter to return explicit errors instead of silently ignoring invalid values. - Improve format_relative_time for proper singular/plural forms. Search: - Validate --after/--updated-after with explicit error messages. - Handle optional title field (Option<String>) in HydratedRow. Show: - Use resolve_project() for project disambiguation. Sync: - Thread robot_mode via SyncOptions for IngestDisplay selection. - Use IngestDisplay::progress_only() in interactive sync mode. GenerateDocs: - Use resolve_project() for --project filtering. Co-Authored-By: Claude (us.anthropic.claude-opus-4-5-20251101-v1:0) <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ use crate::Config;
|
||||
use crate::core::db::create_connection;
|
||||
use crate::core::error::{LoreError, Result};
|
||||
use crate::core::paths::get_db_path;
|
||||
use crate::core::project::resolve_project;
|
||||
use crate::core::time::ms_to_iso;
|
||||
|
||||
/// Merge request metadata for display.
|
||||
@@ -145,18 +146,20 @@ struct IssueRow {
|
||||
/// Find issue by iid, optionally filtered by project.
|
||||
fn find_issue(conn: &Connection, iid: i64, project_filter: Option<&str>) -> Result<IssueRow> {
|
||||
let (sql, params): (&str, Vec<Box<dyn rusqlite::ToSql>>) = match project_filter {
|
||||
Some(project) => (
|
||||
"SELECT i.id, i.iid, i.title, i.description, i.state, i.author_username,
|
||||
i.created_at, i.updated_at, i.web_url, p.path_with_namespace
|
||||
FROM issues i
|
||||
JOIN projects p ON i.project_id = p.id
|
||||
WHERE i.iid = ? AND (p.path_with_namespace = ? OR p.path_with_namespace LIKE ?)",
|
||||
vec![
|
||||
Box::new(iid),
|
||||
Box::new(project.to_string()),
|
||||
Box::new(format!("%/{}", project)),
|
||||
],
|
||||
),
|
||||
Some(project) => {
|
||||
let project_id = resolve_project(conn, project)?;
|
||||
(
|
||||
"SELECT i.id, i.iid, i.title, i.description, i.state, i.author_username,
|
||||
i.created_at, i.updated_at, i.web_url, p.path_with_namespace
|
||||
FROM issues i
|
||||
JOIN projects p ON i.project_id = p.id
|
||||
WHERE i.iid = ? AND i.project_id = ?",
|
||||
vec![
|
||||
Box::new(iid),
|
||||
Box::new(project_id),
|
||||
],
|
||||
)
|
||||
}
|
||||
None => (
|
||||
"SELECT i.id, i.iid, i.title, i.description, i.state, i.author_username,
|
||||
i.created_at, i.updated_at, i.web_url, p.path_with_namespace
|
||||
@@ -333,20 +336,22 @@ struct MrRow {
|
||||
/// Find MR by iid, optionally filtered by project.
|
||||
fn find_mr(conn: &Connection, iid: i64, project_filter: Option<&str>) -> Result<MrRow> {
|
||||
let (sql, params): (&str, Vec<Box<dyn rusqlite::ToSql>>) = match project_filter {
|
||||
Some(project) => (
|
||||
"SELECT m.id, m.iid, m.title, m.description, m.state, m.draft,
|
||||
m.author_username, m.source_branch, m.target_branch,
|
||||
m.created_at, m.updated_at, m.merged_at, m.closed_at,
|
||||
m.web_url, p.path_with_namespace
|
||||
FROM merge_requests m
|
||||
JOIN projects p ON m.project_id = p.id
|
||||
WHERE m.iid = ? AND (p.path_with_namespace = ? OR p.path_with_namespace LIKE ?)",
|
||||
vec![
|
||||
Box::new(iid),
|
||||
Box::new(project.to_string()),
|
||||
Box::new(format!("%/{}", project)),
|
||||
],
|
||||
),
|
||||
Some(project) => {
|
||||
let project_id = resolve_project(conn, project)?;
|
||||
(
|
||||
"SELECT m.id, m.iid, m.title, m.description, m.state, m.draft,
|
||||
m.author_username, m.source_branch, m.target_branch,
|
||||
m.created_at, m.updated_at, m.merged_at, m.closed_at,
|
||||
m.web_url, p.path_with_namespace
|
||||
FROM merge_requests m
|
||||
JOIN projects p ON m.project_id = p.id
|
||||
WHERE m.iid = ? AND m.project_id = ?",
|
||||
vec![
|
||||
Box::new(iid),
|
||||
Box::new(project_id),
|
||||
],
|
||||
)
|
||||
}
|
||||
None => (
|
||||
"SELECT m.id, m.iid, m.title, m.description, m.state, m.draft,
|
||||
m.author_username, m.source_branch, m.target_branch,
|
||||
|
||||
Reference in New Issue
Block a user