diff --git a/htmlreport/cppcheck-htmlreport b/htmlreport/cppcheck-htmlreport index b33699ca2ed..5fd2f5017a7 100755 --- a/htmlreport/cppcheck-htmlreport +++ b/htmlreport/cppcheck-htmlreport @@ -494,9 +494,20 @@ def tr_str(td_th, line, id, cwe, severity, classification, guideline, message, t if classification: items.extend([classification, guideline]) if htmlfile: - ret += '<%s>%d' % (td_th, htmlfile, line, line, td_th) + if htmlfile.startswith("http://") or htmlfile.startswith("https://"): + # GitHub/GitLab style line anchor + href = f"{htmlfile.rstrip('#L1')}#L{line}" + # Emit **line number with link** + ret += f'<{td_th}>{line}' + else: + # local HTML annotated + href = f"{htmlfile}#line-{line}" + # Emit **line number with link** + ret += f'<{td_th}>{line}' + + # Emit id, cwe, severity, classification, ... for item in items: - ret += '<%s>%s' % (td_th, item, td_th) + ret += f'<{td_th}>{item}' else: items.insert(0,line) for item in items: @@ -675,7 +686,9 @@ def main() -> None: 'written.') parser.add_argument('--source-dir', dest='source_dir', help='Base directory where source code files can be ' - 'found.') + 'found, or a URL to a remote GitHub/GitLab ' + 'repository including a branch, e.g. ' + '--source-dir=https://github.com///blob//') parser.add_argument('--add-author-information', dest='add_author_information', help='Blame information to include. ' 'Adds specified author information. ' @@ -705,6 +718,10 @@ def main() -> None: if options.source_dir: source_dir = options.source_dir + is_remote = False + if source_dir.startswith("http://") or source_dir.startswith("https://"): + is_remote = True + add_author_information = [] if options.add_author_information: fields = [x.strip() for x in options.add_author_information.split(',')] @@ -753,9 +770,14 @@ def main() -> None: for error in contentHandler.errors: filename = error['file'] if filename not in files: - files[filename] = { - 'errors': [], 'htmlfile': str(file_no) + '.html'} - file_no = file_no + 1 + if is_remote: + # Construct remote URL for GitHub/GitLab + # tr_str() will use the actual line number, so we can just start with line 1 + remote_url = source_dir.rstrip('/') + '/' + filename + '#L1' + files[filename] = {'errors': [], 'htmlfile': remote_url} + else: + files[filename] = {'errors': [], 'htmlfile': str(file_no) + '.html'} + file_no += 1 files[filename]['errors'].append(error) # Make sure that the report directory is created if it doesn't exist. @@ -795,6 +817,11 @@ def main() -> None: if filename == '': continue + if is_remote: + # Remote source: do NOT generate local annotated HTML files. + # The index will still point directly to GitHub/GitLab URLs. + continue + source_filename = os.path.join(source_dir, filename) try: with io.open(source_filename, 'r', encoding=options.source_encoding) as input_file: diff --git a/man/manual-premium.md b/man/manual-premium.md index 6ae337a9fb0..9f2e5992537 100644 --- a/man/manual-premium.md +++ b/man/manual-premium.md @@ -1158,14 +1158,41 @@ The output screen says: Default is reading from stdin. --report-dir=REPORT_DIR The directory where the html report content is written. - --source-dir=SOURCE_DIR - Base directory where source code files can be found. + --source-dir=SOURCE_DIR|URL + Base directory where source code files can be found, or + a URL to a remote GitHub/GitLab repository including a + branch, e.g.: + --source-dir=https://github.com///blob// Example usage: cppcheck gui/test.cpp --xml 2> err.xml cppcheck-htmlreport --file=err.xml --report-dir=test1 --source-dir=. +or + cppcheck gui/test.cpp --xml 2> err.xml + cppcheck-htmlreport --file=err.xml --report-dir=test1 \ + --source-dir=https://github.com///blob// + +## Choosing Between Local Annotated HTML and Remote Repository Links + +cppcheck-htmlreport supports two modes for linking to source files: + - Local annotated HTML files (default when `--source-dir` is a filesystem path) + - Remote GitHub/GitLab links (when `--source-dir` is a URL) + +Pointing `--source-dir` to a filesystem path generates local annotated HTML files. +This is useful when you need a fully self-contained report that works offline, +includes inline annotations, and is ideal for small or medium projects where +generation is fast. +Using a remote GitHub/GitLab URL avoids generating per-file HTML and keeps the +summary report lightweight and fast to produce. This mode is ideal when the +source is already hosted online and local duplication is unnecessary. +Remote mode is especially helpful when the HTML report may be public or widely +distributed but the source code should remain private, since access control is +handled by the hosting service. +In general, local mode fits air-gapped environments, while remote mode works +best for CI workflows and large or private repositories. + # Check Level ## Reduced diff --git a/man/manual.md b/man/manual.md index cc1182ab9ab..68a59109666 100644 --- a/man/manual.md +++ b/man/manual.md @@ -1182,14 +1182,41 @@ The output screen says: Default is reading from stdin. --report-dir=REPORT_DIR The directory where the html report content is written. - --source-dir=SOURCE_DIR - Base directory where source code files can be found. + --source-dir=SOURCE_DIR|URL + Base directory where source code files can be found, or + a URL to a remote GitHub/GitLab repository including a + branch, e.g.: + --source-dir=https://github.com///blob// Example usage: cppcheck gui/test.cpp --xml 2> err.xml cppcheck-htmlreport --file=err.xml --report-dir=test1 --source-dir=. +or + cppcheck gui/test.cpp --xml 2> err.xml + cppcheck-htmlreport --file=err.xml --report-dir=test1 \ + --source-dir=https://github.com///blob// + +## Choosing Between Local Annotated HTML and Remote Repository Links + +cppcheck-htmlreport supports two modes for linking to source files: + - Local annotated HTML files (default when `--source-dir` is a filesystem path) + - Remote GitHub/GitLab links (when `--source-dir` is a URL) + +Pointing `--source-dir` to a filesystem path generates local annotated HTML files. +This is useful when you need a fully self-contained report that works offline, +includes inline annotations, and is ideal for small or medium projects where +generation is fast. +Using a remote GitHub/GitLab URL avoids generating per-file HTML and keeps the +summary report lightweight and fast to produce. This mode is ideal when the +source is already hosted online and local duplication is unnecessary. +Remote mode is especially helpful when the HTML report may be public or widely +distributed but the source code should remain private, since access control is +handled by the hosting service. +In general, local mode fits air-gapped environments, while remote mode works +best for CI workflows and large or private repositories. + # Check Level ## Reduced