coverage.in 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #!@GUILE@ --no-auto-compile
  2. -*- scheme -*-
  3. !#
  4. ;;; Template for generating lcov coverage reports
  5. ;;; guile-semver --- Semantic Versioning tooling for guile
  6. ;;; Borrowing code from:
  7. ;;; The Geesh Shell Interpreter
  8. ;;; Copyright 2017 Timothy Sample <samplet@ngyro.com>
  9. ;;;
  10. ;;; coverage.in: This file is part of guile-semver.
  11. ;;;
  12. ;;; guile-semver is free software; you can redistribute it and/or modify it
  13. ;;; under the terms of the GNU General Public License as published by the Free
  14. ;;; Software Foundation; either version 3 of the License, or (at your option)
  15. ;;; any later version.
  16. ;;;
  17. ;;; guile-semver is distributed in the hope that it will be useful, but
  18. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  19. ;;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  20. ;;; for more details.
  21. ;;;
  22. ;;; You should have received a copy of the GNU General Public License along
  23. ;;; with guile-semver. If not, see <http://www.gnu.org/licenses/>.
  24. (use-modules (ice-9 popen)
  25. (ice-9 receive)
  26. (ice-9 textual-ports)
  27. (srfi srfi-11)
  28. (srfi srfi-26)
  29. (system vm coverage)
  30. (system vm vm))
  31. ;; This is a standard Guile function. However, even though it is
  32. ;; specified in the manual, it does not support the MODULES
  33. ;; keyword. It's only a one-line change, which I've made here.
  34. (define* (coverage-data->lcov data port #:key (modules #f))
  35. ;; Output per-file coverage data.
  36. (format port "TN:~%")
  37. (for-each (lambda (file)
  38. (let ((path (search-path %load-path file)))
  39. (if (string? path)
  40. (begin
  41. (format port "SF:~A~%" path)
  42. (for-each (lambda (line+count)
  43. (let ((line (car line+count))
  44. (count (cdr line+count)))
  45. (format port "DA:~A,~A~%"
  46. (+ 1 line) count)))
  47. (line-execution-counts data file))
  48. (let-values (((instr exec)
  49. (instrumented/executed-lines data file)))
  50. (format port "LH: ~A~%" exec)
  51. (format port "LF: ~A~%" instr))
  52. (format port "end_of_record~%"))
  53. (begin
  54. (format (current-error-port)
  55. "skipping unknown source file: ~a~%"
  56. file)))))
  57. (or modules (instrumented-source-files data))))
  58. (define (project-file? file)
  59. "Determine if @var{file} is part of the current project."
  60. (let ((path (search-path %load-path file)))
  61. (string-contains path "@abs_top_srcdir@")))
  62. (define (list-tests)
  63. "List the tests specified in the @file{Makefile}."
  64. (let* ((port (open-pipe* OPEN_READ "make"
  65. "-f" "@abs_top_srcdir@/Makefile" "test-list"))
  66. (tests (filter (lambda (x)
  67. (and (not (string-null? x))
  68. (string-suffix? ".scm" x)))
  69. (string-split (get-string-all port)
  70. char-whitespace?)))
  71. (status (close-pipe port)))
  72. (when (not (eqv? 0 (status:exit-val status)))
  73. (error "Cannot get test list"))
  74. (map (cut string-append "@abs_top_srcdir@/" <>) tests)))
  75. (receive (data result)
  76. (call-with-vm
  77. (lambda ()
  78. (set-vm-engine! 'debug)
  79. (with-code-coverage
  80. (lambda ()
  81. (for-each load (list-tests))))))
  82. (let ((port (open-output-file "lcov.info"))
  83. (modules (filter project-file? (instrumented-source-files data))))
  84. (coverage-data->lcov data port #:modules modules)
  85. (close port)))