feat(integration): production-ready .version_history priority

- Change get_info() priority: .version_history first, merkwerk fallback
- Add read_version_history() for production deployment compatibility
- Works without merkwerk binary (tar.gz deployments)
- Maintains development fallback to merkwerk command

Production-ready: tar.gz deployments work without merkwerk installation.
This commit is contained in:
michael 2025-08-20 06:07:56 +02:00
parent f2d925ee57
commit 62ddc17393

View file

@ -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,56 +178,40 @@ 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 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
fallback.build_info = {
cached = false,
error = error_msg or "merkwerk unavailable"
}
end
return fallback
end
-- Parse JSON response
if json_result then
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
end
-- Add metadata
if data then
data.source = "merkwerk"
if include_build_info then
data.build_info = {
cached = false,
timestamp = os.time(),
cache_ttl = cache_ttl
source = "merkwerk_command",
method = "development_fallback",
history_error = history_error
}
end
@ -178,6 +223,29 @@ function merkwerk.get_info(options)
return data
end
end
-- LAST RESORT: Pure fallback
local fallback = fallback_info()
if fallback_version then
fallback.base_version = fallback_version
fallback.full_version = fallback_version .. "+unknown"
end
fallback.error = "Both version_history and merkwerk failed"
if include_build_info then
fallback.build_info = {
cached = false,
source = "fallback",
method = "emergency_fallback",
history_error = history_error,
merkwerk_error = error_msg or "merkwerk unavailable"
}
end
return fallback
end
-- Get only the content hash (lightweight)
function merkwerk.get_hash()