feat(arty): generate full Markdown doc in notes command
- New generate_notes_md(): builds title, description blockquote, dependencies table, per-script fenced blocks, and details section from the entire arty.yml using existing yq helpers - show_notes() now accepts --raw to print raw Markdown; formatted mode pipes through the same glow/mdcat/python3 render pipeline - Removes the decorative ━━━ border (clashes with full-document output) - main() passes args[] through to show_notes for flag forwarding Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1005,46 +1005,138 @@ list_libs() {
|
|||||||
echo
|
echo
|
||||||
}
|
}
|
||||||
|
|
||||||
# Display notes from arty.yml with markdown rendering
|
# Generate a comprehensive Markdown document from arty.yml
|
||||||
show_notes() {
|
generate_notes_md() {
|
||||||
local config_file="${1:-$ARTY_CONFIG_FILE}"
|
local config_file="${1:-$ARTY_CONFIG_FILE}"
|
||||||
|
local md=""
|
||||||
|
|
||||||
if [[ ! -f "$config_file" ]]; then
|
# Read top-level fields
|
||||||
log_error "Config file not found: $config_file"
|
local name version description author license url notes
|
||||||
|
name=$(get_yaml_field "$config_file" "name")
|
||||||
|
version=$(get_yaml_field "$config_file" "version")
|
||||||
|
description=$(get_yaml_field "$config_file" "description")
|
||||||
|
author=$(get_yaml_field "$config_file" "author")
|
||||||
|
license=$(get_yaml_field "$config_file" "license")
|
||||||
|
url=$(get_yaml_field "$config_file" "url")
|
||||||
|
notes=$(yq eval '.notes' "$config_file" 2>/dev/null)
|
||||||
|
|
||||||
|
# Null-clean
|
||||||
|
[[ "$name" == "null" || -z "$name" ]] && name="$(basename "$PWD")"
|
||||||
|
[[ "$version" == "null" ]] && version=""
|
||||||
|
[[ "$description" == "null" ]] && description=""
|
||||||
|
[[ "$author" == "null" ]] && author=""
|
||||||
|
[[ "$license" == "null" ]] && license=""
|
||||||
|
[[ "$url" == "null" ]] && url=""
|
||||||
|
[[ "$notes" == "null" ]] && notes=""
|
||||||
|
|
||||||
|
# Title
|
||||||
|
if [[ -n "$version" ]]; then
|
||||||
|
md+="# ${name} · v${version}"$'\n\n'
|
||||||
|
else
|
||||||
|
md+="# ${name}"$'\n\n'
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Description as blockquote
|
||||||
|
if [[ -n "$description" ]]; then
|
||||||
|
while IFS= read -r line; do
|
||||||
|
md+="> ${line}"$'\n'
|
||||||
|
done <<< "$description"
|
||||||
|
md+=$'\n'
|
||||||
|
md+="---"$'\n\n'
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Overview (.notes field)
|
||||||
|
if [[ -n "$notes" ]]; then
|
||||||
|
md+="## Overview"$'\n\n'
|
||||||
|
md+="${notes}"$'\n\n'
|
||||||
|
md+="---"$'\n\n'
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Dependencies table
|
||||||
|
local ref_count
|
||||||
|
ref_count=$(yq eval '.references | length' "$config_file" 2>/dev/null)
|
||||||
|
if [[ "$ref_count" =~ ^[0-9]+$ ]] && [[ "$ref_count" -gt 0 ]]; then
|
||||||
|
md+="## Dependencies"$'\n\n'
|
||||||
|
md+="| Package | Location | Ref |"$'\n'
|
||||||
|
md+="|---------|----------|-----|"$'\n'
|
||||||
|
for ((i=0; i<ref_count; i++)); do
|
||||||
|
local ref_data ref_url ref_into ref_ref pkg_name _rest _rest2
|
||||||
|
ref_data=$(parse_reference "$config_file" "$i")
|
||||||
|
ref_url="${ref_data%%|*}"
|
||||||
|
_rest="${ref_data#*|}"
|
||||||
|
ref_into="${_rest%%|*}"
|
||||||
|
_rest2="${_rest#*|}"
|
||||||
|
ref_ref="${_rest2%%|*}"
|
||||||
|
pkg_name=$(get_lib_name "$ref_url")
|
||||||
|
[[ -z "$ref_into" ]] && ref_into=".arty/libs/${pkg_name}"
|
||||||
|
[[ -z "$ref_ref" ]] && ref_ref="—"
|
||||||
|
md+="| \`${pkg_name}\` | \`${ref_into}\` | ${ref_ref} |"$'\n'
|
||||||
|
done
|
||||||
|
md+=$'\n'
|
||||||
|
md+="---"$'\n\n'
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Scripts
|
||||||
|
local script_names
|
||||||
|
script_names=$(list_yaml_scripts "$config_file" 2>/dev/null)
|
||||||
|
if [[ -n "$script_names" ]]; then
|
||||||
|
md+="## Scripts"$'\n\n'
|
||||||
|
while IFS= read -r script_name; do
|
||||||
|
[[ -z "$script_name" ]] && continue
|
||||||
|
local cmd
|
||||||
|
cmd=$(get_yaml_script "$config_file" "$script_name")
|
||||||
|
[[ "$cmd" == "null" || -z "$cmd" ]] && continue
|
||||||
|
md+="### \`${script_name}\`"$'\n\n'
|
||||||
|
md+="\`\`\`sh"$'\n'
|
||||||
|
md+="${cmd}"$'\n'
|
||||||
|
md+="\`\`\`"$'\n\n'
|
||||||
|
done <<< "$script_names"
|
||||||
|
md+="---"$'\n\n'
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Details
|
||||||
|
local has_details=0
|
||||||
|
[[ -n "$author" ]] && has_details=1
|
||||||
|
[[ -n "$license" ]] && has_details=1
|
||||||
|
[[ -n "$url" ]] && has_details=1
|
||||||
|
if [[ "$has_details" -eq 1 ]]; then
|
||||||
|
md+="## Details"$'\n\n'
|
||||||
|
[[ -n "$author" ]] && md+="- **Author**: ${author}"$'\n'
|
||||||
|
[[ -n "$license" ]] && md+="- **License**: ${license}"$'\n'
|
||||||
|
[[ -n "$url" ]] && md+="- **URL**: [${url}](${url})"$'\n'
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '%s' "$md"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Display notes from arty.yml — generated from the full config
|
||||||
|
show_notes() {
|
||||||
|
local raw_mode=0
|
||||||
|
for arg in "$@"; do [[ "$arg" == "--raw" ]] && raw_mode=1; done
|
||||||
|
|
||||||
|
if [[ ! -f "$ARTY_CONFIG_FILE" ]]; then
|
||||||
|
log_error "Config file not found: $ARTY_CONFIG_FILE"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Get notes field from YAML
|
local md
|
||||||
local notes=$(yq eval '.notes' "$config_file" 2>/dev/null)
|
md=$(generate_notes_md "$ARTY_CONFIG_FILE")
|
||||||
|
|
||||||
if [[ -z "$notes" ]] || [[ "$notes" == "null" ]]; then
|
if [[ "$raw_mode" -eq 1 ]]; then
|
||||||
log_info "No notes found in $config_file"
|
printf '%s\n' "$md"
|
||||||
log_info "Add a 'notes' field to your arty.yml to display project notes"
|
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Get project name for header
|
|
||||||
local project_name=$(get_yaml_field "$config_file" "name")
|
|
||||||
[[ "$project_name" == "null" ]] && project_name="$(basename "$PWD")"
|
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo -e "${BOLD}${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
||||||
echo -e "${BOLD}${GREEN} Notes: ${project_name}${NC}"
|
|
||||||
echo -e "${BOLD}${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Try to render markdown with available tools
|
|
||||||
if command -v glow &>/dev/null; then
|
if command -v glow &>/dev/null; then
|
||||||
# Use glow if available (best option)
|
printf '%s\n' "$md" | glow -
|
||||||
echo "$notes" | glow -
|
|
||||||
elif command -v mdcat &>/dev/null; then
|
elif command -v mdcat &>/dev/null; then
|
||||||
# Use mdcat if available (good alternative)
|
printf '%s\n' "$md" | mdcat
|
||||||
echo "$notes" | mdcat
|
|
||||||
elif command -v python3 &>/dev/null; then
|
elif command -v python3 &>/dev/null; then
|
||||||
# Fallback to Python markdown rendering - create temp file to avoid quoting issues
|
local tmp
|
||||||
local temp_notes=$(mktemp)
|
tmp=$(mktemp)
|
||||||
echo "$notes" > "$temp_notes"
|
printf '%s\n' "$md" > "$tmp"
|
||||||
python3 - "$temp_notes" <<'EOPY' 2>/dev/null || echo "$notes"
|
python3 - "$tmp" <<'EOPY' 2>/dev/null || printf '%s\n' "$md"
|
||||||
import sys
|
import sys
|
||||||
import re
|
import re
|
||||||
|
|
||||||
@@ -1102,14 +1194,10 @@ text = re.sub(r'^(\d+)\. (.+)$', r' \1. \2', text, flags=re.MULTILINE)
|
|||||||
|
|
||||||
print(text)
|
print(text)
|
||||||
EOPY
|
EOPY
|
||||||
rm -f "$temp_notes"
|
rm -f "$tmp"
|
||||||
else
|
else
|
||||||
# Absolute fallback: just print the raw text
|
printf '%s\n' "$md"
|
||||||
echo "$notes"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo
|
|
||||||
echo -e "${BOLD}${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
|
||||||
echo
|
echo
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1537,7 +1625,7 @@ main() {
|
|||||||
list_libs
|
list_libs
|
||||||
;;
|
;;
|
||||||
notes)
|
notes)
|
||||||
show_notes
|
show_notes "${args[@]}"
|
||||||
;;
|
;;
|
||||||
scripts)
|
scripts)
|
||||||
list_scripts
|
list_scripts
|
||||||
|
|||||||
Reference in New Issue
Block a user