Skip to content

Commit 893a99c

Browse files
committed
cli(run,errors): clean sanitizer output, unify timeout logic, and refine code frame context
- Remove redundant runtime timeout handling; rely on effective_timeout_sec() - Drop ASan abort banner lines (==PID==ABORTING) from printed output - Normalize UBSan output by removing extra blank line after 'runtime error' - Improve runtime log filtering to avoid duplicated/noisy sanitizer lines - Refine CodeFrame context trimming: - Remove whitespace-only and brace-only lines ({, }, };) from context - Prevent context compensation that reintroduces noise - Ensure main error line is never trimmed - Fix CodeFrame prefix spacing when expanded line is empty - Clean up dead variables and redundant logic in RunProcess - Minor UX fixes in NewCommand flow uncovered during refactor Result: clearer sanitizer diagnostics, stable timeout behavior, and tighter, noise-free code frames
1 parent 39fcd76 commit 893a99c

5 files changed

Lines changed: 154 additions & 45 deletions

File tree

src/commands/NewCommand.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,12 +223,15 @@ int main()
223223
static bool dir_is_empty(const fs::path &p)
224224
{
225225
std::error_code ec;
226+
226227
if (!dir_exists(p))
227228
return true;
228-
auto it = fs::directory_iterator(p, ec);
229+
230+
fs::directory_iterator it(p, ec);
229231
if (ec)
230232
return false;
231-
return it == fs::end(it);
233+
234+
return it == fs::directory_iterator{};
232235
}
233236

234237
static bool ensure_dir(const fs::path &p, std::string &err)

src/commands/RunCommand.cpp

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,7 @@ namespace vix::commands::RunCommand
583583
}
584584
#endif
585585

586-
progress.phase_done("Build project", "test executed");
586+
progress.phase_done("Run application", "test executed");
587587
if (showUi)
588588
success("🏃 Test executed (library project).");
589589

@@ -620,10 +620,6 @@ namespace vix::commands::RunCommand
620620
#else
621621
std::string runCmd = quote(exePath.string());
622622

623-
int timeout = opt.timeoutSec;
624-
if (opt.forceServerLike || opt.watch)
625-
timeout = 0;
626-
627623
const LiveRunResult rr = run_cmd_live_filtered_capture(
628624
runCmd,
629625
/*spinnerLabel=*/"",
@@ -672,16 +668,18 @@ namespace vix::commands::RunCommand
672668

673669
if (started)
674670
{
675-
progress.phase_done("Build project", "application started");
671+
progress.phase_done("Run application", "completed");
676672
if (showUi)
677673
success("🏃 Application started (preset: " + buildPreset + ").");
678674
}
679675
else
680676
{
681-
progress.phase_done("Build project", "stopped");
677+
progress.phase_done("Run application", "stopped");
682678
}
683679

684680
return 0;
681+
682+
return 0;
685683
}
686684
return 0;
687685
}
@@ -737,14 +735,9 @@ namespace vix::commands::RunCommand
737735
return code != 0 ? code : 4;
738736
}
739737

738+
progress.phase_done("Configure project", "completed (fallback)");
740739
if (showUi)
741-
{
742-
progress.phase_done("Configure project", "completed (fallback)");
743740
std::cout << "\n";
744-
}
745-
746-
progress.phase_done("Configure project", "completed (fallback)");
747-
std::cout << "\n";
748741
}
749742
else
750743
{

src/commands/run/RunProcess.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,42 @@ namespace vix::commands::RunCommand::detail
509509
lastPrintedChar = '\r';
510510
}
511511

512+
static bool is_sanitizer_abort_banner_line(std::string_view line) noexcept
513+
{
514+
// Trim left
515+
while (!line.empty() && (line.front() == ' ' || line.front() == '\t' || line.front() == '\r'))
516+
line.remove_prefix(1);
517+
518+
// ==12345==ABORTING
519+
if (line.size() >= 4 && line.rfind("==", 0) == 0 &&
520+
line.find("==ABORTING") != std::string_view::npos)
521+
return true;
522+
523+
return false;
524+
}
525+
526+
static inline std::string drop_sanitizer_abort_banner_lines(const std::string &chunk)
527+
{
528+
std::string out;
529+
out.reserve(chunk.size());
530+
531+
std::size_t start = 0;
532+
while (start < chunk.size())
533+
{
534+
const std::size_t nl = chunk.find('\n', start);
535+
const std::size_t end = (nl == std::string::npos) ? chunk.size() : (nl + 1);
536+
537+
std::string_view line(&chunk[start], end - start);
538+
539+
if (!is_sanitizer_abort_banner_line(line))
540+
out.append(line.data(), line.size());
541+
542+
start = end;
543+
}
544+
545+
return out;
546+
}
547+
512548
LiveRunResult run_cmd_live_filtered_capture(
513549
const std::string &cmd,
514550
const std::string &spinnerLabel,
@@ -1045,6 +1081,8 @@ namespace vix::commands::RunCommand::detail
10451081
if (!filtered.empty())
10461082
{
10471083
std::string toPrint = drop_vix_error_tip_lines(filtered);
1084+
if (!toPrint.empty())
1085+
toPrint = drop_sanitizer_abort_banner_lines(toPrint);
10481086

10491087
if (!toPrint.empty() && !captureOnly)
10501088
{

src/errors/CodeFrame.cpp

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,18 @@ namespace vix::cli::errors
3838
return true;
3939
}
4040

41+
static bool isWhitespaceOnly(const std::string &s)
42+
{
43+
for (unsigned char c : s)
44+
{
45+
if (c == '\r' || c == '\n')
46+
continue;
47+
if (std::isspace(c) == 0)
48+
return false;
49+
}
50+
return true;
51+
}
52+
4153
static std::string expandTabs(const std::string &s, int tabWidth)
4254
{
4355
if (tabWidth <= 0)
@@ -143,6 +155,29 @@ namespace vix::cli::errors
143155
<< caretColor << caretSlice << resetColor << "\n";
144156
}
145157

158+
static bool isContextNoiseLine(const std::string &s)
159+
{
160+
// trim spaces/tabs
161+
std::size_t i = 0;
162+
while (i < s.size() && (s[i] == ' ' || s[i] == '\t' || s[i] == '\r'))
163+
++i;
164+
165+
std::size_t j = s.size();
166+
while (j > i && (s[j - 1] == ' ' || s[j - 1] == '\t' || s[j - 1] == '\r'))
167+
--j;
168+
169+
if (j <= i)
170+
return true; // empty/whitespace
171+
172+
const std::string_view t(&s[i], j - i);
173+
174+
// treat only braces as noise in context
175+
if (t == "{" || t == "}" || t == "};")
176+
return true;
177+
178+
return false;
179+
}
180+
146181
void printCodeFrame(
147182
const CompilerError &err,
148183
const ErrorContext &ctx,
@@ -160,8 +195,16 @@ namespace vix::cli::errors
160195
if (err.line > n)
161196
return;
162197

163-
const int from = std::max(1, err.line - opt.contextLines);
164-
const int to = std::min(n, err.line + opt.contextLines);
198+
int from = std::max(1, err.line - opt.contextLines);
199+
int to = std::min(n, err.line + opt.contextLines);
200+
201+
// trim bottom noise lines (never trim the main line)
202+
while (to > err.line && isContextNoiseLine(lines[static_cast<std::size_t>(to - 1)]))
203+
--to;
204+
205+
// trim top noise lines (never trim the main line)
206+
while (from < err.line && isContextNoiseLine(lines[static_cast<std::size_t>(from - 1)]))
207+
++from;
165208

166209
const std::size_t width = std::to_string(to).size();
167210

@@ -180,8 +223,11 @@ namespace vix::cli::errors
180223
const std::size_t pad = (width > lnStr.size()) ? (width - lnStr.size()) : 0;
181224

182225
std::ostringstream p;
183-
p << " " << std::string(pad, ' ') << lnStr << " | ";
184-
const std::string prefix = p.str();
226+
p << " " << std::string(pad, ' ') << lnStr << " |";
227+
const std::string prefixBase = p.str();
228+
229+
const bool addGap = !expanded.empty();
230+
const std::string prefixPrint = addGap ? (prefixBase + " ") : prefixBase;
185231

186232
if (!isMain)
187233
{
@@ -200,25 +246,25 @@ namespace vix::cli::errors
200246
cropped += "";
201247
}
202248

203-
std::cerr << GRAY << prefix << cropped << RESET << "\n";
249+
if (cropped.empty())
250+
std::cerr << GRAY << prefixPrint << RESET << "\n";
251+
else
252+
std::cerr << GRAY << prefixPrint << cropped << RESET << "\n";
204253
}
205254
else
206255
{
207-
std::cerr << GRAY << prefix << expanded << RESET << "\n";
256+
// no crop needed
257+
if (expanded.empty())
258+
std::cerr << GRAY << prefixPrint << RESET << "\n";
259+
else
260+
std::cerr << GRAY << prefixPrint << expanded << RESET << "\n";
208261
}
262+
209263
continue;
210264
}
211265

212266
const std::string caret = makeCaretLine(err.column, opt.tabWidth, rawLine);
213-
214-
printTruncatedLineWithPrefix(
215-
expanded,
216-
caret,
217-
opt.maxLineWidth,
218-
prefix,
219-
/*lineColor=*/"", // main line normal
220-
/*caretColor=*/RED, // caret red
221-
/*resetColor=*/RESET);
267+
printTruncatedLineWithPrefix(expanded, caret, opt.maxLineWidth, prefixPrint, "", RED, RESET);
222268
}
223269
}
224270

0 commit comments

Comments
 (0)