diff --git a/integrations/lua-api.lua b/integrations/lua-api.lua index cd96832..0d15243 100644 --- a/integrations/lua-api.lua +++ b/integrations/lua-api.lua @@ -70,6 +70,67 @@ local function parse_json_response(json_str) return data end +-- Read latest entry from .version_history file +local function read_version_history() + local file = io.open(".version_history", "r") + if not file then + return nil, "No .version_history file found" + end + + local last_line = nil + for line in file:lines() do + -- Skip comment lines + if not line:match("^%s*#") and line:match("%S") then + last_line = line + end + end + file:close() + + if not last_line then + return nil, ".version_history contains no valid entries" + end + + -- Parse: content_hash,vcs_hash,branch,timestamp,author,vcs_type,project_type + local parts = {} + for part in last_line:gmatch("([^,]+)") do + table.insert(parts, part) + end + + if #parts < 7 then + return nil, "Invalid .version_history format" + end + + -- Get base version from VERSION file if available + local base_version = "?.?.?" + local version_file = io.open("VERSION", "r") + if version_file then + local version_content = version_file:read("*line") + if version_content and not version_content:match("^%s*$") then + base_version = version_content:match("^%s*(.-)%s*$") + end + version_file:close() + end + + -- Build response in same format as merkwerk + local data = { + project_name = parts[7] and parts[7]:gsub("-api$", "") or "unknown", -- lua-api → lua + project_type = parts[7] or "unknown", + base_version = base_version, + content_hash = parts[1] or "unknown", + full_version = base_version .. "+" .. (parts[1] or "unknown"), + version = base_version .. "+" .. (parts[1] or "unknown"), + timestamp = parts[4] or "", + vcs = { + type = parts[6] or "none", + hash = parts[2] or "", + branch = parts[3] or "" + }, + source = "version_history" + } + + return data, nil +end + -- Generate fallback info when merkwerk is unavailable local function fallback_info() return { @@ -96,7 +157,7 @@ local function is_cache_valid(ttl) return cache.data and (current_time - cache.timestamp) < ttl end --- Get version information with caching +-- Get version information with NEW priority order function merkwerk.get_info(options) options = options or {} local use_cache = options.cache ~= false @@ -117,66 +178,73 @@ function merkwerk.get_info(options) return result end - -- Execute merkwerk command + -- PRODUCTION PRIORITY: Try .version_history FIRST + local history_data, history_error = read_version_history() + if history_data then + -- Success: Use version history data + if include_build_info then + history_data.build_info = { + cached = false, + source = "version_history", + method = "production_ready" + } + end + + -- Update cache + if use_cache then + cache.data = history_data + cache.timestamp = os.time() + end + + return history_data + end + + -- FALLBACK: Try merkwerk command (development/testing) local json_result, error_msg = execute_merkwerk("info --json") + if json_result then + local data = parse_json_response(json_result) + if data then + data.source = "merkwerk" - if not json_result then - -- merkwerk failed - use fallback - local fallback = fallback_info() - if fallback_version then - fallback.base_version = fallback_version - fallback.full_version = fallback_version .. "+unknown" - end - if error_msg then - fallback.error = error_msg - end + if include_build_info then + data.build_info = { + cached = false, + source = "merkwerk_command", + method = "development_fallback", + history_error = history_error + } + end - if include_build_info then - fallback.build_info = { - cached = false, - error = error_msg or "merkwerk unavailable" - } - end + -- Update cache + if use_cache then + cache.data = data + cache.timestamp = os.time() + end - return fallback + return data + end end - -- Parse JSON response - local data = parse_json_response(json_result) - if not data then - -- JSON parsing failed - use fallback - local fallback = fallback_info() - fallback.error = "Failed to parse merkwerk JSON output" - - if include_build_info then - fallback.build_info = { - cached = false, - error = "JSON parsing failed", - raw_output = json_result:sub(1, 100) -- First 100 chars for debugging - } - end - - return fallback + -- LAST RESORT: Pure fallback + local fallback = fallback_info() + if fallback_version then + fallback.base_version = fallback_version + fallback.full_version = fallback_version .. "+unknown" end - -- Add metadata - data.source = "merkwerk" + fallback.error = "Both version_history and merkwerk failed" if include_build_info then - data.build_info = { + fallback.build_info = { cached = false, - timestamp = os.time(), - cache_ttl = cache_ttl + source = "fallback", + method = "emergency_fallback", + history_error = history_error, + merkwerk_error = error_msg or "merkwerk unavailable" } end - -- Update cache - if use_cache then - cache.data = data - cache.timestamp = os.time() - end - - return data + return fallback end -- Get only the content hash (lightweight)