fix(scraper): relative python module import path

This commit is contained in:
Barrett Ruth 2025-09-19 20:55:06 -04:00
parent b12844c3a0
commit 514761733b
4 changed files with 62 additions and 55 deletions

View file

@ -10,7 +10,6 @@
local M = {} local M = {}
---Parse git diff markers and extract highlight information
---@param text string Raw git diff output line ---@param text string Raw git diff output line
---@return string cleaned_text, DiffHighlight[] ---@return string cleaned_text, DiffHighlight[]
local function parse_diff_line(text) local function parse_diff_line(text)
@ -52,7 +51,6 @@ local function parse_diff_line(text)
return result_text, highlights return result_text, highlights
end end
---Parse complete git diff output
---@param diff_output string ---@param diff_output string
---@return ParsedDiff ---@return ParsedDiff
function M.parse_git_diff(diff_output) function M.parse_git_diff(diff_output)
@ -64,10 +62,8 @@ function M.parse_git_diff(diff_output)
local content_lines = {} local content_lines = {}
local all_highlights = {} local all_highlights = {}
-- Skip git diff header lines
local content_started = false local content_started = false
for _, line in ipairs(lines) do for _, line in ipairs(lines) do
-- Skip header lines (@@, +++, ---, index, etc.)
if if
content_started content_started
or ( or (
@ -80,33 +76,27 @@ function M.parse_git_diff(diff_output)
then then
content_started = true content_started = true
-- Process content lines
if line:match('^%+') then if line:match('^%+') then
-- Added line - remove + prefix and parse highlights local clean_line = line:sub(2)
local clean_line = line:sub(2) -- Remove + prefix
local parsed_line, line_highlights = parse_diff_line(clean_line) local parsed_line, line_highlights = parse_diff_line(clean_line)
table.insert(content_lines, parsed_line) table.insert(content_lines, parsed_line)
-- Set line numbers for highlights
local line_num = #content_lines local line_num = #content_lines
for _, highlight in ipairs(line_highlights) do for _, highlight in ipairs(line_highlights) do
highlight.line = line_num - 1 -- 0-based for extmarks highlight.line = line_num - 1
table.insert(all_highlights, highlight) table.insert(all_highlights, highlight)
end end
elseif not line:match('^%-') and not line:match('^\\') then -- Skip removed lines and "\ No newline" messages elseif not line:match('^%-') and not line:match('^\\') then
-- Word-diff content line or unchanged line
local clean_line = line:match('^%s') and line:sub(2) or line local clean_line = line:match('^%s') and line:sub(2) or line
local parsed_line, line_highlights = parse_diff_line(clean_line) local parsed_line, line_highlights = parse_diff_line(clean_line)
-- Only add non-empty lines
if parsed_line ~= '' then if parsed_line ~= '' then
table.insert(content_lines, parsed_line) table.insert(content_lines, parsed_line)
-- Set line numbers for highlights
local line_num = #content_lines local line_num = #content_lines
for _, highlight in ipairs(line_highlights) do for _, highlight in ipairs(line_highlights) do
highlight.line = line_num - 1 -- 0-based for extmarks highlight.line = line_num - 1
table.insert(all_highlights, highlight) table.insert(all_highlights, highlight)
end end
end end
@ -120,12 +110,10 @@ function M.parse_git_diff(diff_output)
} }
end end
---Apply highlights to a buffer using extmarks
---@param bufnr number ---@param bufnr number
---@param highlights DiffHighlight[] ---@param highlights DiffHighlight[]
---@param namespace number ---@param namespace number
function M.apply_highlights(bufnr, highlights, namespace) function M.apply_highlights(bufnr, highlights, namespace)
-- Clear existing highlights in this namespace
vim.api.nvim_buf_clear_namespace(bufnr, namespace, 0, -1) vim.api.nvim_buf_clear_namespace(bufnr, namespace, 0, -1)
for _, highlight in ipairs(highlights) do for _, highlight in ipairs(highlights) do
@ -139,13 +127,11 @@ function M.apply_highlights(bufnr, highlights, namespace)
end end
end end
---Create namespace for diff highlights
---@return number ---@return number
function M.create_namespace() function M.create_namespace()
return vim.api.nvim_create_namespace('cp_diff_highlights') return vim.api.nvim_create_namespace('cp_diff_highlights')
end end
---Parse and apply git diff to buffer
---@param bufnr number ---@param bufnr number
---@param diff_output string ---@param diff_output string
---@param namespace number ---@param namespace number

View file

@ -53,37 +53,40 @@ local function format_exit_code(code)
return signal_name and string.format('%d (%s)', code, signal_name) or tostring(code) return signal_name and string.format('%d (%s)', code, signal_name) or tostring(code)
end end
-- Compute column widths + aggregates
local function compute_cols(test_state) local function compute_cols(test_state)
local w = { num = 3, status = 8, time = 6, exit = 11, limits = 12 } local w = { num = 3, status = 8, time = 6, exit = 11, timeout = 8, memory = 8 }
local limits_str = '' local timeout_str = ''
local memory_str = ''
if test_state.constraints then if test_state.constraints then
limits_str = timeout_str = tostring(test_state.constraints.timeout_ms)
string.format('%d/%.0f', test_state.constraints.timeout_ms, test_state.constraints.memory_mb) memory_str = string.format('%.0f', test_state.constraints.memory_mb)
else else
limits_str = '' timeout_str = ''
memory_str = ''
end end
for i, tc in ipairs(test_state.test_cases) do for i, tc in ipairs(test_state.test_cases) do
local prefix = (i == test_state.current_index) and '>' or ' ' local prefix = (i == test_state.current_index) and '>' or ' '
w.num = math.max(w.num, #(prefix .. i)) w.num = math.max(w.num, #(' ' .. prefix .. i .. ' '))
w.status = math.max(w.status, #(' ' .. M.get_status_info(tc).text)) w.status = math.max(w.status, #(' ' .. M.get_status_info(tc).text .. ' '))
local time_str = tc.time_ms and string.format('%.2f', tc.time_ms) or '' local time_str = tc.time_ms and string.format('%.2f', tc.time_ms) or ''
w.time = math.max(w.time, #time_str) w.time = math.max(w.time, #(' ' .. time_str .. ' '))
w.exit = math.max(w.exit, #(' ' .. format_exit_code(tc.code))) w.exit = math.max(w.exit, #(' ' .. format_exit_code(tc.code) .. ' '))
w.limits = math.max(w.limits, #limits_str) w.timeout = math.max(w.timeout, #(' ' .. timeout_str .. ' '))
w.memory = math.max(w.memory, #(' ' .. memory_str .. ' '))
end end
w.num = math.max(w.num, #' # ') w.num = math.max(w.num, #' # ')
w.status = math.max(w.status, #' Status ') w.status = math.max(w.status, #' Status ')
w.time = math.max(w.time, #' Runtime (ms) ') w.time = math.max(w.time, #' Runtime (ms) ')
w.exit = math.max(w.exit, #' Exit Code ') w.exit = math.max(w.exit, #' Exit Code ')
w.limits = math.max(w.limits, #' Time (ms)/Mem (MB)') w.timeout = math.max(w.timeout, #' Time (ms) ')
w.memory = math.max(w.memory, #' Mem (MB) ')
local sum = w.num + w.status + w.time + w.exit + w.limits local sum = w.num + w.status + w.time + w.exit + w.timeout + w.memory
local inner = sum + 4 -- four inner vertical dividers local inner = sum + 5
local total = inner + 2 -- two outer borders local total = inner + 2
return { w = w, sum = sum, inner = inner, total = total } return { w = w, sum = sum, inner = inner, total = total }
end end
@ -97,11 +100,12 @@ local function center(text, width)
end end
local function right_align(text, width) local function right_align(text, width)
local pad = width - #text local content = (' %s '):format(text)
local pad = width - #content
if pad <= 0 then if pad <= 0 then
return text return content
end end
return string.rep(' ', pad) .. text return string.rep(' ', pad) .. content
end end
local function top_border(c) local function top_border(c)
@ -115,7 +119,9 @@ local function top_border(c)
.. '' .. ''
.. string.rep('', w.exit) .. string.rep('', w.exit)
.. '' .. ''
.. string.rep('', w.limits) .. string.rep('', w.timeout)
.. ''
.. string.rep('', w.memory)
.. '' .. ''
end end
@ -130,7 +136,9 @@ local function row_sep(c)
.. '' .. ''
.. string.rep('', w.exit) .. string.rep('', w.exit)
.. '' .. ''
.. string.rep('', w.limits) .. string.rep('', w.timeout)
.. ''
.. string.rep('', w.memory)
.. '' .. ''
end end
@ -145,7 +153,9 @@ local function bottom_border(c)
.. '' .. ''
.. string.rep('', w.exit) .. string.rep('', w.exit)
.. '' .. ''
.. string.rep('', w.limits) .. string.rep('', w.timeout)
.. ''
.. string.rep('', w.memory)
.. '' .. ''
end end
@ -160,7 +170,9 @@ local function flat_fence_above(c)
.. '' .. ''
.. string.rep('', w.exit) .. string.rep('', w.exit)
.. '' .. ''
.. string.rep('', w.limits) .. string.rep('', w.timeout)
.. ''
.. string.rep('', w.memory)
.. '' .. ''
end end
@ -175,7 +187,9 @@ local function flat_fence_below(c)
.. '' .. ''
.. string.rep('', w.exit) .. string.rep('', w.exit)
.. '' .. ''
.. string.rep('', w.limits) .. string.rep('', w.timeout)
.. ''
.. string.rep('', w.memory)
.. '' .. ''
end end
@ -194,7 +208,9 @@ local function header_line(c)
.. '' .. ''
.. center('Exit Code', w.exit) .. center('Exit Code', w.exit)
.. '' .. ''
.. center('Time (ms)/Mem (MB)', w.limits) .. center('Time (ms)', w.timeout)
.. ''
.. center('Mem (MB)', w.memory)
.. '' .. ''
end end
@ -205,12 +221,14 @@ local function data_row(c, idx, tc, is_current, test_state)
local time = tc.time_ms and string.format('%.2f', tc.time_ms) or '' local time = tc.time_ms and string.format('%.2f', tc.time_ms) or ''
local exit = format_exit_code(tc.code) local exit = format_exit_code(tc.code)
local limits = '' local timeout = ''
local memory = ''
if test_state.constraints then if test_state.constraints then
limits = timeout = tostring(test_state.constraints.timeout_ms)
string.format('%d/%.0f', test_state.constraints.timeout_ms, test_state.constraints.memory_mb) memory = string.format('%.0f', test_state.constraints.memory_mb)
else else
limits = '' timeout = ''
memory = ''
end end
local line = '' local line = ''
@ -222,13 +240,16 @@ local function data_row(c, idx, tc, is_current, test_state)
.. '' .. ''
.. right_align(exit, w.exit) .. right_align(exit, w.exit)
.. '' .. ''
.. right_align(limits, w.limits) .. right_align(timeout, w.timeout)
.. ''
.. right_align(memory, w.memory)
.. '' .. ''
local hi local hi
if status.text ~= '' then if status.text ~= '' then
local pad = w.status - #status.text local content = ' ' .. status.text .. ' '
local status_start_col = 1 + w.num + 1 + pad local pad = w.status - #content
local status_start_col = 1 + w.num + 1 + pad + 1
local status_end_col = status_start_col + #status.text local status_end_col = status_start_col + #status.text
hi = { hi = {
col_start = status_start_col, col_start = status_start_col,

View file

@ -7,7 +7,7 @@ from dataclasses import asdict
import cloudscraper import cloudscraper
from bs4 import BeautifulSoup, Tag from bs4 import BeautifulSoup, Tag
from models import MetadataResult, ProblemSummary, TestCase, TestsResult from scrapers.models import MetadataResult, ProblemSummary, TestCase, TestsResult
def scrape(url: str) -> list[TestCase]: def scrape(url: str) -> list[TestCase]:

View file

@ -8,7 +8,7 @@ from dataclasses import asdict
import requests import requests
from bs4 import BeautifulSoup, Tag from bs4 import BeautifulSoup, Tag
from models import MetadataResult, ProblemSummary, TestCase, TestsResult from scrapers.models import MetadataResult, ProblemSummary, TestCase, TestsResult
def parse_problem_url(problem_input: str) -> str | None: def parse_problem_url(problem_input: str) -> str | None: