Giter VIP home page Giter VIP logo

excoveralls's Introduction

ExCoveralls

Build Status Coverage Status hex.pm version hex.pm downloads hex.pm license Last Updated

An Elixir library that reports test coverage statistics, with the option to post to coveralls.io service. It uses Erlang's cover to generate coverage information, and posts the test coverage results to coveralls.io through the JSON API.

The following are example projects.

Settings

mix.exs

Add the following parameters.

  • test_coverage: [tool: ExCoveralls] for using ExCoveralls for coverage reporting.
  • test_coverage: [tool: ExCoveralls, export: "cov"] for exporting data to cover/cov.coverdata
  • preferred_cli_env: [coveralls: :test] for running mix coveralls in :test env by default
    • It's an optional setting for skipping MIX_ENV=test part when executing mix coveralls tasks.
  • test_coverage: [test_task: "espec"] if you use Espec instead of default ExUnit.
  • :excoveralls in the deps function.
  • Application.put_env(:excoveralls, :base_path, "/bash/path") an optional config if you want to set the application root path explicitly. By default this is the directory that the mix.exs file is in.
def project do
  [
    app: :excoveralls,
    version: "1.0.0",
    elixir: "~> 1.0.0",
    deps: deps(),
    test_coverage: [tool: ExCoveralls],
    preferred_cli_env: [
      coveralls: :test,
      "coveralls.detail": :test,
      "coveralls.post": :test,
      "coveralls.html": :test,
      "coveralls.cobertura": :test
    ]
    # if you want to use espec,
    # test_coverage: [tool: ExCoveralls, test_task: "espec"]
  ]
end

defp deps do
  [
    {:excoveralls, "~> 0.18", only: :test},
  ]
end

Note on umbrella application: If you want to use Excoveralls within an umbrella project, every apps must have test_coverage: [tool: ExCoveralls] in the mix.exs of each app.

Note: If you're using earlier than elixir v1.3, MIX_ENV=test or preferred_cli_env may be required for running mix tasks. Refer to PR#96 for the details.

Usage

Mix Tasks

[mix coveralls] Show coverage

Run the MIX_ENV=test mix coveralls command to show coverage information on localhost. This task locally prints out the coverage information. It doesn't submit the results to the server.

$ MIX_ENV=test mix coveralls
...
----------------
COV    FILE                                        LINES RELEVANT   MISSED
100.0% lib/excoveralls/general.ex                     28        4        0
 75.0% lib/excoveralls.ex                             54        8        2
 94.7% lib/excoveralls/stats.ex                       70       19        1
100.0% lib/excoveralls/poster.ex                      16        3        0
 95.5% lib/excoveralls/local.ex                       79       22        1
100.0% lib/excoveralls/travis.ex                      23        3        0
100.0% lib/mix/tasks.ex                               44        8        0
100.0% lib/excoveralls/cover.ex                       32        5        0
[TOTAL]  94.4%
----------------

Specifying the --help option displays the options list for available tasks.

Usage: mix coveralls <Options>
  Used to display coverage

  <Options>
    -h (--help)         Show helps for excoveralls mix tasks

    Common options across coveralls mix tasks

    -o (--output-dir)   Write coverage information to output dir.
    -u (--umbrella)     Show overall coverage for umbrella project.
    -v (--verbose)      Show json string for posting.
    --subdir            Git repo sub directory: This will be added to the the front of file path, use if your covered
                        file paths reside within a subfolder of the git repo. Example: If your source file path is
                        "test.ex", and your git repo root is one directory up making the file's relative path
                        "src/lib/test.ex", then the sub directory should be: "src/lib" (from coveralls.io)
    --rootdir           This will be stripped from the file path in order to resolve the relative path of this repo's
                        files. It should be the path to your git repo's root on your CI build environment. This is not
                        needed if your source file path is already relative. It's used to pull the source file from the
                        github repo, so must be exact. Example: If your source file path is "/home/runs/app/test.ex",
                        and your git repo resides in "app", then the root path should be: "/home/runs/app/" (from
                        coveralls.io)
    --flagname          Job flag name which will be shown in the Coveralls UI
    --import-cover      Directory from where '.coverdata' files should be imported and their results added to the report.
                        Coverdata is imported after tests are run.

Usage: mix coveralls.detail [--filter file-name-pattern]
  Used to display coverage with detail
  [--filter file-name-pattern] can be used to limit the files to be displayed in detail.

Usage: mix coveralls.travis [--pro]
  Used to post coverage from Travis CI server.

Usage: mix coveralls.github
  Used to post coverage from [GitHub Actions](https://github.com/features/actions).

Usage: mix coveralls.post <Options>
  Used to post coverage from local server using token.
  The token should be specified in the argument or in COVERALLS_REPO_TOKEN
  environment variable.

  <Options>
    -t (--token)        Repository token ('REPO TOKEN' of coveralls.io)
    -n (--name)         Service name ('VIA' column at coveralls.io page)
    -b (--branch)       Branch name ('BRANCH' column at coveralls.io page)
    -c (--committer)    Committer name ('COMMITTER' column at coveralls.io page)
    -m (--message)      Commit message ('COMMIT' column at coveralls.io page)
    -s (--sha)          Commit SHA (required when not using Travis)
    --build             Service number ('BUILDS' column at coveralls.io page)
    --parallel          coveralls.io 'parallel' option (See coveralls.io API Reference)

[mix coveralls.travis] Post coverage from travis

Specify mix coveralls.travis as the build script in the .travis.yml and explicitly set the MIX_ENV environment to TEST. This task submits the result to Coveralls when the build is executed on Travis CI.

.travis.yml

language: elixir

elixir:
  - 1.2.0

otp_release:
  - 18.0

env:
  - MIX_ENV=test

script: mix coveralls.travis

If you're using Travis Pro for a private project, Use coveralls.travis --pro and ensure your coveralls.io repo token is available via the COVERALLS_REPO_TOKEN environment variable.

[mix coveralls.github] Post coverage from GitHub Actions

Specify mix coveralls.github as the build script in the GitHub action YML file and explicitly set the MIX_ENV environment to test and add GITHUB_TOKEN with the value of {{ secrets.GITHUB_TOKEN }}, this is required because is used internally by coveralls.io to check the action and add statuses.

The value of secrets.GITHUB_TOKEN is added automatically inside every GitHub action, so you not need to assign that.

This task submits the result to Coveralls when the build is executed via GitHub actions and add statuses in the checks of github.

.github/workflows/example.yml

on: push

jobs:
  test:
    runs-on: ubuntu-latest
    name: OTP ${{matrix.otp}} / Elixir ${{matrix.elixir}}
    strategy:
      matrix:
        otp: [21.3.8.10, 22.1.7]
        elixir: [1.8.2, 1.9.4]
    env:
      MIX_ENV: test
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    steps:
      - uses: actions/[email protected]
      - uses: erlef/setup-beam@v1
        with:
          otp-version: ${{matrix.otp}}
          elixir-version: ${{matrix.elixir}}
      - run: mix deps.get
      - run: mix coveralls.github

[mix coveralls.circle] Post coverage from circle

Specify mix coveralls.circle in the circle.yml. This task is for submitting the result to the coveralls server when Circle-CI build is executed.

circle.yml

test:
  override:
    - mix coveralls.circle

Ensure your coveralls.io repo token is available via the COVERALLS_REPO_TOKEN environment variable.

[mix coveralls.semaphore] Post coverage from semaphore

Specify mix coveralls.semaphore in the build command prompt for instructions in semaphore. This task is for submitting the result to the coveralls server when Semaphore-CI build is executed.

semaphore build instructions

mix coveralls.semaphore

Ensure your coveralls.io repo token is available via the COVERALLS_REPO_TOKEN environment variable.

[mix coveralls.drone] Post coverage from drone

Specify mix coveralls.drone in the .drone.yml. This task is for submitting the result to the coveralls server when the Drone build is executed.

You will also need to add your coveralls repo token as a secret to the drone project: drone secret add --repository=your-namespace/your-project --name=coveralls_repo_token --value=xyz

.drone.yml

pipeline:
  build:
    secrets: [ coveralls_repo_token ]
    commands:
      - mix coveralls.drone

[mix coveralls.post] Post coverage from any host

Acquire the repository token of coveralls.io in advance, and run the mix coveralls.post command. It is for submitting the result to coveralls server from any host.

The token can be specified as a mix task option (--token), or as an environment variable (COVERALLS_REPO_TOKEN).

MIX_ENV=test mix coveralls.post --token [YOUR_TOKEN] --branch "master" --name "local host" --committer "committer name" --sha "fd80a4c" --message "commit message"
....................................................................................................

Finished in 6.3 seconds (0.7s on load, 5.6s on tests)
100 tests, 0 failures

Randomized with seed 800810
Successfully uploaded the report to 'https://coveralls.io'.

For the detailed option description, check mix coveralls --help task.

[mix coveralls.detail] Show coverage with detail

This task displays coverage information at the source-code level with colored text. Green indicates a tested line, and red indicates lines which are not tested. When reviewing many source files, pipe the output to the less program (with the -R option for color) to paginate the results.

$ MIX_ENV=test mix coveralls.detail | less -R
...
----------------
COV    FILE                                        LINES RELEVANT   MISSED
100.0% lib/excoveralls/general.ex                     28        4        0
...
[TOTAL]  94.4%

--------lib/excoveralls.ex--------
defmodule ExCoveralls do
  @moduledoc """
  Provides the entry point for coverage calculation and output.
  This module method is called by Mix.Tasks.Test
...

Also, displayed source code can be filtered by specifying arguments (it will be matched against the FILE column value). The following example lists the source code only for general.ex.

$ MIX_ENV=test mix coveralls.detail --filter general.ex
...
----------------
COV    FILE                                        LINES RELEVANT   MISSED
100.0% lib/excoveralls/general.ex                     28        4        0
...
[TOTAL]  94.4%

--------lib/excoveralls.ex--------
defmodule ExCoveralls do
  @moduledoc """
  Provides the entry point for coverage calculation and output.
  This module method is called by Mix.Tasks.Test
...

[mix coveralls.html] Show coverage as HTML report

This task displays coverage information at the source-code level formatted as an HTML page. The report follows the format inspired by HTMLCov from the Mocha testing library in JS. Output to the shell is the same as running the command mix coveralls (to suppress this output, add "print_summary": false to your project's coveralls.json file). In a similar manner to mix coveralls.detail, reported source code can be filtered by specifying arguments using the --filter flag.

$ MIX_ENV=test mix coveralls.html

HTML Report

Output reports are written to cover/excoveralls.html by default, however, the path can be specified by overwriting the "output_dir" coverage option. Custom reports can be created and utilized by defining template_path in coveralls.json. This directory should contain an eex template named coverage.html.eex.

[mix coveralls.json] Show coverage as JSON report

This task displays coverage information at the source-code level formatted as a JSON document. The report follows a format supported by several code coverage services, including Codecov and Code Climate. Output to the shell is the same as running the command mix coveralls (to suppress this output, add "print_summary": false to your project's coveralls.json file). In a similar manner to mix coveralls.detail, reported source code can be filtered by specifying arguments using the --filter flag.

Upload a coverage report to Codecov using their bash uploader or to Code Climate using their test-reporter.

Output reports are written to cover/excoveralls.json by default, however, the path can be specified by overwriting the "output_dir" coverage option.

[mix coveralls.xml] Show coverage as XML report

This task displays coverage information at the source-code level formatted as a XML document. The report follows a format supported by several code coverage services like SonarQube. Output to the shell is the same as running the command mix coveralls (to suppress this output, add "print_summary": false to your project's coveralls.json file). In a similar manner to mix coveralls.detail, reported source code can be filtered by specifying arguments using the --filter flag.

Output reports are written to cover/excoveralls.xml by default, however, the path can be specified by overwriting the "output_dir" coverage option.

[mix coveralls.cobertura] Show coverage as Cobertura report

This task displays coverage information at the source-code level formatted as a Cobertura document. The report follows a format supported by Gitlab code coverage visualization. Output to the shell is the same as running the command mix coveralls (to suppress this output, add "print_summary": false to your project's coveralls.json file). In a similar manner to mix coveralls.detail, reported source code can be filtered by specifying arguments using the --filter flag.

Output reports are written to cover/cobertura.xml by default, however, the path can be specified by overwriting the "output_dir" coverage option.

[mix coveralls.lcov] Show coverage as lcov report (Experimental)

This task displays coverage information at the line level formatted as a lcov. The report follows a format supported by several code coverage services like VSCode extension(ryanluker.vscode-coverage-gutters). Output to the shell is the same as running the command mix coveralls (to suppress this output, add "print_summary": false to your project's coveralls.json file). In a similar manner to mix coveralls.detail, reported source code can be filtered by specifying arguments using the --filter flag.

Output reports are written to cover/lcov.info by default, however, the path can be specified by overwriting the "output_dir" coverage option.

coveralls.json

coveralls.json provides settings for excoveralls.

The default coveralls.json file is stored in deps/excoveralls/lib/conf, and custom coveralls.json files can be placed in the mix project root. The custom definition is prioritized over the default one (if definitions in the custom file are not found, then the definitions in the default file are used).

Stop Words

Stop words defined in coveralls.json will be excluded from the coverage calculation. Some kernel macros defined in Elixir are not considered "covered" by Erlang's cover library. It can be used for excluding these macros, or for any other reasons. The words are parsed as regular expression.

Exclude Files

If you want to exclude/ignore files from the coverage calculation add the skip_files key in the coveralls.json file. skip_files takes an array of file paths, for example:

{
  "skip_files": [
    "folder_to_skip",
    "folder/file_to_skip.ex"
  ]
}

Path should contain a string that can be compiled to Elixir regex, you can test them running Regex.compile("your_path") in your iex shell.

Note that this doesn't work directly in an umbrella project. If you need to exclude files within an app, you should create a separate coveralls.json at the root of the app's folder and add a skip_files key to that file. Paths should be relative to that file, not the umbrella project.

Terminal Report Output

When using in umbrella projects the default report may trim files names when viewing report in terminal.

If you want to change the column width used for file names add the file_column_width key to the terminal_options key in the coveralls.json, for example:

{
  "terminal_options": {
    "file_column_width": 40
  }
}

If you want to see only the total coverage without a table of each file, set the print_files option to false:

{
  "terminal_options": {
    "print_files": false
  }
}

Coverage Options

  • treat_no_relevant_lines_as_covered
    • By default, coverage for [files with no relevant lines] are displayed as 0% for aligning with coveralls.io behavior. But, if treat_no_relevant_lines_as_covered is set to true, it will be displayed as 100%.
  • output_dir
    • The directory which the HTML report will output to. Defaulted to cover/.
  • template_path
    • A custom path for html reports. This defaults to the htmlcov report in the excoveralls lib.
  • minimum_coverage
    • When set to a number greater than 0, this setting causes the mix coveralls and mix coveralls.html tasks to exit with a status code of 1 if test coverage falls below the specified threshold (defaults to 0). This is useful to interrupt CI pipelines with strict code coverage rules. Should be expressed as a number between 0 and 100 signifying the minimum percentage of lines covered.
  • html_filter_full_covered
    • A boolean, when true files with 100% coverage are not shown in the HTML report. Default to false.
  • floor_coverage
    • A boolean, when false coverage values are ceiled instead of floored, this means that a project with some lines that are not covered can still have a total 100% coverage. Default to true.

Example configuration file:

{
  "default_stop_words": [
    "defmodule",
    "defrecord",
    "defimpl",
    "def.+(.+\/\/.+).+do"
  ],

  "custom_stop_words": [
  ],

  "coverage_options": {
    "treat_no_relevant_lines_as_covered": true,
    "output_dir": "cover/",
    "template_path": "custom/path/to/template/",
    "minimum_coverage": 90,
    "xml_base_dir": "custom/path/for/xml/reports/",
    "html_filter_full_covered": true
  }
}

Other Considerations

Ignore Lines

Use comments coveralls-ignore-start and coveralls-ignore-stop to ignore certain lines from code coverage calculation.

defmodule MyModule do
  def covered do
  end

  # coveralls-ignore-start
  def ignored do
  end
  # coveralls-ignore-stop
end

Use comment coveralls-ignore-next-line to ignore only the next line.

defmodule MyModule do
  def covered do
    # coveralls-ignore-next-line
    "ignored"
    "covered"
  end
end

Silence OTP Cover Warnings

To remove OTP warnings about modules or specific logging, you can copy the cover.erl file under src/ of your Elixir project and modify it to remove the warnings, as a tentative solution.

imported_info(_Text,_Module,_Imported) ->
    ok.

Merging Coverage Results

ExCoveralls can include .coverdata files in the result of the current test run through the --import-cover flag. This can be used to include coverage data from partitioned tests or integration tests that may run in a subprocess, for instance.

Coverage data is generated when running mix test --cover, optionally with the --export-coverage flag to specify an output name.

$ mix test --only integration --cover --export-coverage integration-coverage
Excluding tags: [:test]
Including tags: [:integration]
... test run omitted ...
# Coverage data written to cover/integration-coverage.coverdata

# Report coverage, do not run integration tests
$ mix coveralls --exclude integration
Excluding tags: [:integration]
... test run omitted ...

----------------
COV    FILE                                        LINES RELEVANT   MISSED
...
[TOTAL]  80.2% # <-- This result does not include coverage from integration tests
----------------

# Report coverage, do not run integration tests, but include previously written coverdata
$ mix coveralls --exclude integration --import-cover cover
Excluding tags: [:integration]
... test run omitted ...

----------------
COV    FILE                                        LINES RELEVANT   MISSED
...
[TOTAL]  95.3% # <-- This result now includes coverage from integration tests
----------------

Coverage data is imported after tests are run.

See the mix test Coverage documentation for more information on .coverdata.

Configuring HTTP Options in ExCoveralls

You can customize the HTTP options used by :httpc when posting results. The example below shows how to specify a custom cacertfile:

config :excoveralls,
  http_options: [
    timeout: 10_000,
    ssl: [
      # Refer to the secure coding guide:
      # https://erlef.github.io/security-wg/secure_coding_and_deployment_hardening/inets
      verify: :verify_peer,
      depth: 2,
      customize_hostname_check: [
        match_fun: :public_key.pkix_verify_hostname_match_fun(:https)
      ],
      cacertfile: to_charlist(System.fetch_env!("TEST_COVERAGE_CACERTFILE"))
    ]

By default, ExCoveralls uses the cacertfile from castore when the dependency is installed. If it's not available and you're running Erlang 25 or later, the system will attempt to use the OS certificates via :public_key.cacerts_load/0.

Notes

  • If mock library is used, it will show some warnings during execution.
  • In case Erlang clashes at mix coveralls, executing mix test in advance might avoid the error.
  • When erlang version 17.3 is used, an error message (MatchError) no match of right hand side value: "" can be shown. Refer to issue #14 for the details.

Todo

  • It might not work well on projects which handle multiple project (Mix.Project) files.
    • Needs improvement on file-path handling.

License

This source code is licensed under the MIT license. Copyright (c) 2013-present, parroty.

excoveralls's People

Contributors

albertored avatar andrewdryga avatar captchrisd avatar dhaspden avatar ericmj avatar erikreedstrom avatar fenollp avatar fhunleth avatar gmcabrita avatar gmile avatar hirotnk avatar leifg avatar ma2gedev avatar mononym avatar nathany avatar nickmerwin avatar parroty avatar pragmaticivan avatar rkushnir avatar robertdober avatar romankotov avatar satoren avatar slogsdon avatar smeevil avatar solar05 avatar sulphur avatar tarzan avatar techgaun avatar trumant avatar whatyouhide avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

excoveralls's Issues

Argument error in version 0.3.8

In version 0.3.8 I'm seeing this error message when trying to mix coveralls:

** (ArgumentError) argument error
    (stdlib) :maps.find("treat_no_relevant_lines_as_covered", [{"treat_no_relevant_lines_as_covered", false}])
    lib/excoveralls/local.ex:104: ExCoveralls.Local.default_coverage_value/0
    lib/excoveralls/local.ex:75: ExCoveralls.Local.format_info/1
    (elixir) lib/enum.ex:977: anonymous fn/3 in Enum.map/2
    (elixir) lib/enum.ex:1261: Enum."-reduce/3-lists^foldl/2-0-"/3
    (elixir) lib/enum.ex:977: Enum.map/2
    lib/excoveralls/local.ex:67: ExCoveralls.Local.coverage/1
    lib/excoveralls/local.ex:19: ExCoveralls.Local.execute/2

I am not seeing this error in version 0.3.7.

Some information about my environment:

$ iex -S mix
Erlang/OTP 17 [erts-6.3] [source] [64-bit] [smp:4:4] [async-threads:10] [kernel-poll:false]

Interactive Elixir (1.0.3)

Travis build not working

Randomized with seed 23244
** (exit) exited in: :gen_fsm.sync_send_all_state_event(#PID<0.441.0>, {:start, 8000}, :infinity)
    ** (EXIT) an exception was raised:
        ** (MatchError) no match of right hand side value: ""
            (ssl) ssl_handshake.erl:1737: :ssl_handshake.dec_hello_extensions/2
            (ssl) ssl_handshake.erl:926: :ssl_handshake.decode_handshake/3
            (ssl) tls_handshake.erl:155: :tls_handshake.get_tls_handshake_aux/3
            (ssl) tls_connection.erl:433: :tls_connection.next_state/4
            (stdlib) gen_fsm.erl:503: :gen_fsm.handle_msg/7
            (stdlib) proc_lib.erl:237: :proc_lib.init_p_do_apply/3
    (stdlib) gen_fsm.erl:242: :gen_fsm.sync_send_all_state_event/3
    (ssl) ssl_connection.erl:1654: :ssl_connection.sync_send_all_state_event/2
    (ssl) ssl_connection.erl:101: :ssl_connection.handshake/2
    (ssl) tls_connection.erl:81: :tls_connection.start_fsm/8
    (ssl) ssl_connection.erl:71: :ssl_connection.connect/8
    (hackney) src/hackney_connect/hackney_connect.erl:241: :hackney_connect.do_connect/5
    (hackney) src/hackney_connect/hackney_connect.erl:30: :hackney_connect.connect/5
    (hackney) src/hackney_client/hackney.erl:309: :hackney.request/5

Running mix task in the :dev env results in test deps not being loaded

Hello!

Given these deps:

    [
      {:shouldi, only: :test},
      {:excoveralls, only: [:dev,:test]},
    ]

$ mix coveralls fails, due to ShouldI not being loaded in :dev.

louis ~/projects/dogma [master *] $ mix coveralls
==> idna (compile)
==> ssl_verify_hostname (compile)
==> jsx
Compiled src/jsx_decoder.erl
Compiled src/jsx_encoder.erl
Compiled src/jsx_config.erl
Compiled src/jsx_parser.erl
Compiled src/jsx.erl
Compiled src/jsx_to_term.erl
Compiled src/jsx_verify.erl
Compiled src/jsx_to_json.erl
Generated jsx app
==> exjsx
Compiled lib/jsx.ex
Generated exjsx app
==> hackney (compile)
==> excoveralls
Compiled lib/excoveralls/path_reader.ex
Compiled lib/excoveralls/post.ex
Compiled lib/excoveralls/cover.ex
Compiled lib/excoveralls.ex
Compiled lib/excoveralls/conf_server.ex
Compiled lib/excoveralls/poster.ex
Compiled lib/excoveralls/task/util.ex
Compiled lib/excoveralls/travis.ex
Compiled lib/excoveralls/stop_words.ex
Compiled lib/excoveralls/settings.ex
Compiled lib/excoveralls/stats.ex
Compiled lib/excoveralls/exceptions.ex
Compiled lib/excoveralls/local.ex
Compiled lib/mix/tasks.ex
Generated excoveralls app
==> dogma
Compiled lib/dogma/rules.ex
Compiled lib/dogma/formatter.ex
Compiled lib/dogma/error.ex
Compiled lib/dogma.ex
Compiled lib/dogma/rules/unless_else.ex
Compiled lib/dogma/rules/trailing_whitespace.ex
Compiled lib/dogma/rules/line_length.ex
Compiled lib/mix/tasks/dogma.ex
Compiled lib/dogma/formatter/simple.ex
Compiled lib/dogma/script.ex
Generated dogma app
** (CompileError) test/dogma/formatter/simple_test.exs:2: module ShouldI is not loaded and could not be found
    (elixir) expanding macro: Kernel.use/1
    test/dogma/formatter/simple_test.exs:2: Dogma.Formatter.SimpleTest (module)
    (elixir) lib/code.ex:307: Code.require_file/2

If I run it in :test, it works. (MIX_ENV=test mix coveralls)

Thanks,
Louis

Documentation: include mix coveralls.html preferred_cli_env

I found it a bit confusing after copy/pasting some config and running:

mix coveralls.html

to get this error:

** (Mix) The task "coveralls.html" could not be found

why not include it in the README:

preferred_cli_env: ["coveralls": :test, "coveralls.detail": :test, "coveralls.html": :test, "coveralls.post": :test],

SQL Sandbox Mode

Is there any way to turn SQL Sandbox Mode on when running coveralls? (We use it on Travis-CI.)

$ mix coveralls.travis --pro
............
Finished in 6.3 seconds
12 tests, 0 failures
Randomized with seed 398467
17:29:59.943 [error] GenServer #PID<0.637.0> terminating
** (DBConnection.OwnershipError) cannot find ownership process for #PID<0.637.0>.
When using ownership, you must manage connections in one
of the three ways:
  * By explicitly checking out a connection
  * By explicitly allowing a spawned process
  * By running the pool in shared mode
The first two options require every new process to explicitly
check a connection out or be allowed by calling checkout or
allow respectively.
The third option requires a {:shared, pid} mode to be set.
If using shared mode in tests, make sure your tests are not
async.
If you are reading this error, it means you have not done one
of the steps above or that the owner process has crashed.
See Ecto.Adapters.SQL.Sandbox docs for more information.
    (db_connection) lib/db_connection.ex:718: DBConnection.checkout/2
    (db_connection) lib/db_connection.ex:619: DBConnection.run/3
    (db_connection) lib/db_connection.ex:463: DBConnection.prepare_execute/4
    (ecto) lib/ecto/adapters/postgres/connection.ex:82: Ecto.Adapters.Postgres.Connection.execute/4
    (ecto) lib/ecto/adapters/sql.ex:228: Ecto.Adapters.SQL.sql_call/6
    (ecto) lib/ecto/adapters/sql.ex:426: Ecto.Adapters.SQL.struct/6
    (ecto) lib/ecto/repo/schema.ex:391: Ecto.Repo.Schema.apply/4
    (ecto) lib/ecto/repo/schema.ex:187: anonymous fn/11 in Ecto.Repo.Schema.do_insert/4
    (ap_api) lib/parser/batch_parser.ex:45: AssetProcessor.Parser.process_loan/1
    (bsoneach) lib/bsoneach.ex:121: BSONEach.apply_callback/2
    (bsoneach) lib/bsoneach.ex:77: BSONEach.iterate/4
    (bsoneach) lib/bsoneach.ex:50: BSONEach.each/2
    (ap_api) lib/parser/batch_parser.ex:30: AssetProcessor.Parser.handle_info/2
    (stdlib) gen_server.erl:601: :gen_server.try_dispatch/4
    (stdlib) gen_server.erl:667: :gen_server.handle_msg/5
    (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
17:30:00.033 [error] GenServer #PID<0.655.0> terminating

BadFunctionError after proper output (Elixir 0.13.2)

Hi!

After an Elixir upgrade to 0.13.2 from 0.12.5,
I got the following error when running mix coveralls.
The funny thing is that the output is OK, then there's the error.

Did the guys changed sth in Mix between 0.13.1 (which you have presumably tested looking at the mix.exs) and 0.13.2 ?

[...]
[TOTAL]  42.1%
----------------
** (BadFunctionError) expected a function, got: :ok
    (mix) lib/mix/tasks/test.ex:169: Mix.Tasks.Test.run/1
    (mix) lib/mix/cli.ex:66: Mix.CLI.run_task/2
    (elixir) src/elixir_lexical.erl:17: :elixir_lexical.run/2
    (elixir) lib/code.ex:303: Code.require_file/2

macros are ignored

Does it supposed to be this way?

mix.exs:

defp deps do
    [
       ...
      {:excoveralls, "~> 0.5", only: :test}
    ]
  end

Result:

$ mix coveralls.html
.............

Finished in 0.1 seconds (0.1s on load, 0.02s on tests)
13 tests, 0 failures

Randomized with seed 989620
----------------
COV    FILE                                        LINES RELEVANT   MISSED
  0.0% lib/ecto_autoslug_field.ex                      2        0        0
100.0% lib/ecto_autoslug_field/slug.ex                35        2        0
  0.0% lib/ecto_autoslug_field/slug_generator.e       48        0        0
  0.0% lib/ecto_autoslug_field/type.ex                14        0        0
[TOTAL] 100.0%
----------------
Generating report...

2016-07-19 18 33 45

MatchError in coveralls.travis on travis

Probably a config issue, but I'm getting a MatchError on travis:

https://travis-ci.org/lpil/dogma/builds/67723421
https://github.com/lpil/dogma/blob/master/.travis.yml

Randomized with seed 67607
** (exit) exited in: :gen_fsm.sync_send_all_state_event(#PID<0.242.0>, {:start, 8000}, :infinity)
    ** (EXIT) an exception was raised:
        ** (MatchError) no match of right hand side value: ""
            (ssl) ssl_handshake.erl:1737: :ssl_handshake.dec_hello_extensions/2
            (ssl) ssl_handshake.erl:926: :ssl_handshake.decode_handshake/3
            (ssl) tls_handshake.erl:155: :tls_handshake.get_tls_handshake_aux/3
            (ssl) tls_connection.erl:433: :tls_connection.next_state/4
            (stdlib) gen_fsm.erl:503: :gen_fsm.handle_msg/7
            (stdlib) proc_lib.erl:237: :proc_lib.init_p_do_apply/3
    (stdlib) gen_fsm.erl:242: :gen_fsm.sync_send_all_state_event/3
    (ssl) ssl_connection.erl:1654: :ssl_connection.sync_send_all_state_event/2
    (ssl) ssl_connection.erl:101: :ssl_connection.handshake/2
    (ssl) tls_connection.erl:81: :tls_connection.start_fsm/8
    (ssl) ssl_connection.erl:71: :ssl_connection.connect/8
    (hackney) src/hackney_connect/hackney_connect.erl:244: :hackney_connect.do_connect/5
    (hackney) src/hackney_connect/hackney_connect.erl:41: :hackney_connect.connect/5
    (hackney) src/hackney_client/hackney.erl:317: :hackney.request/5

What have I done wrong? :)

Thanks,
Louis

Coveralls Badge only Displays Last App Tested in Umbrella App

When displaying the coveralls badge we cannot get the badge to display the overall combined test percentage for the entire umbrella app. It is only displaying the last application that was tested.

Now when we run mix coveralls -u from the command line we get a combined test coverage percentage as we expected.

Has anyone else had this issue? Any input is greatly appreciated.

Files to ignore on a Phoenix project

I'm trying to figure out which files should be ignored that are generated by Phoenix. Does anyone have a list of files that can safely be ignored?

It would be nice to be able to add a quick coveralls.json generation task that would ignore files that you don't need to explicitly test in a web app with Phoenix.

excoveralls errors out on Erlang 19

OS: Darwin Kernel Version 15.6.0
Erlang: 19.1
Elixir: 1.3.4
excoveralls: 0.5.7

The mix test task runs as usual, but running mix coveralls or mix coveralls.html

Output:

nietaki@silver:mainframe-server (master=)$ mix coveralls
The database for Mainframe.Repo has already been created

17:51:20.966 [error] Process #PID<0.285.0> raised an exception
** (ArgumentError) argument error
    (stdlib) erl_anno.erl:318: :erl_anno.set(:location, -1, [location: -1, generated: true])
    (stdlib) erl_parse.yrl:1516: anonymous fn/3 in :erl_parse.map_anno/2
    (stdlib) erl_parse.yrl:1645: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1637: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1648: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
** (exit) an exception was raised:
    ** (ArgumentError) argument error
        (stdlib) erl_anno.erl:318: :erl_anno.set(:location, -1, [location: -1, generated: true])
        (stdlib) erl_parse.yrl:1516: anonymous fn/3 in :erl_parse.map_anno/2
        (stdlib) erl_parse.yrl:1645: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1637: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1648: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
    cover.erl:583: :cover.call/1
    lib/excoveralls.ex:30: ExCoveralls.start/2
    (mix) lib/mix/tasks/test.ex:205: Mix.Tasks.Test.run/1
    (mix) lib/mix/task.ex:296: Mix.Task.run_task/3
    (mix) lib/mix/task.ex:328: Mix.Task.run_alias/3
    (mix) lib/mix/task.ex:261: Mix.Task.run/2
    lib/mix/tasks.ex:53: Mix.Tasks.Coveralls.do_run/2
    (mix) lib/mix/task.ex:296: Mix.Task.run_task/3


17:51:20.975 [error] Process #PID<0.284.0> raised an exception
** (ArgumentError) argument error
    (stdlib) :ets.insert(:cover_internal_clause_table, {Mainframe.Emails.Mailer.Address, [{Mainframe.Emails.Mailer.Address, :__info__, 1, 1, 1}, {Mainframe.Emails.Mailer.Address, :__info__, 1, 2, 1}, {Mainframe.Emails.Mailer.Address, :__info__, 1, 3, 1}, {Mainframe.Emails.Mailer.Address, :__struct__, 0, 1, 1}, {Mainframe.Emails.Mailer.Address, :__struct__, 1, 1, 2}]})
    cover.erl:1584: :cover.do_compile_beam2/5
    cover.erl:1478: :cover.do_compile_beam/3
    (stdlib) lists.erl:1239: :lists.map/2
    (stdlib) lists.erl:1239: :lists.map/2
    cover.erl:2732: anonymous fn/2 in :cover.pmap_spawn/4

17:51:20.975 [error] Process #PID<0.287.0> raised an exception
** (ArgumentError) argument error
    (stdlib) :ets.insert(:cover_internal_data_table, {{:bump, Mainframe.Models.Subscription, :__info__, 1, 1, 0}, 0})
    cover.erl:1789: :cover.munge_body/4
    cover.erl:1740: :cover.munge_clauses/4
    cover.erl:1719: :cover.munge/4
    cover.erl:1635: :cover.transform_2/5
    cover.erl:1620: :cover.transform/3
    cover.erl:1568: :cover.do_compile_beam2/5
    cover.erl:1478: :cover.do_compile_beam/3

17:51:20.976 [error] Process #PID<0.290.0> raised an exception
** (ArgumentError) argument error
    (stdlib) :ets.insert(:cover_internal_clause_table, {Mainframe.Uref, [{Mainframe.Uref, :__info__, 1, 1, 1}, {Mainframe.Uref, :__info__, 1, 2, 1}, {Mainframe.Uref, :__info__, 1, 3, 1}, {Mainframe.Uref, :admin_uref, 1, 1, 1}, {Mainframe.Uref, :admin_username, 1, 1, 1}, {Mainframe.Uref, :email, 2, 1, 1}, {Mainframe.Uref, :"MACRO-email_address", 2, 1, 1}, {Mainframe.Uref, :"MACRO-email_cid", 2, 1, 1}, {Mainframe.Uref, :filter_email, 1, 1, 1}, {Mainframe.Uref, :filter_native, 1, 1, 1}, {Mainframe.Uref, :format_uref, 1, 1, 1}, {Mainframe.Uref, :format_uref, 1, 2, 1}, {Mainframe.Uref, :"MACRO-is_admin?", 2, 1, 1}, {Mainframe.Uref, :"MACRO-is_email?", 2, 1, 1}, {Mainframe.Uref, :"MACRO-is_internal?", 2, 1, 1}, {Mainframe.Uref, :"MACRO-is_native?", 2, 1, 1}, {Mainframe.Uref, :"MACRO-is_system?", 2, 1, 1}, {Mainframe.Uref, :"MACRO-is_uref?", 2, 1, 1}, {Mainframe.Uref, :"MACRO-native_uid", 2, 1, 1}, {Mainframe.Uref, :parse_args, 2, 1, 1}, {Mainframe.Uref, :parse_args, 2, 2, 1}, {Mainframe.Uref, :parse_uref, 1, 1, 3}, {Mainframe.Uref, :system_uref, 0, 1, 1}, {Mainframe.Uref, :uid_to_uref, 1, 1, 1}]})
    cover.erl:1584: :cover.do_compile_beam2/5
    cover.erl:1478: :cover.do_compile_beam/3
    (stdlib) lists.erl:1239: :lists.map/2
    (stdlib) lists.erl:1239: :lists.map/2
    cover.erl:2732: anonymous fn/2 in :cover.pmap_spawn/4

17:51:20.977 [error] Process #PID<0.286.0> raised an exception
** (ArgumentError) argument error
    (stdlib) :ets.insert(:cover_internal_clause_table, {Mainframe.Models.AccountStorage, [{Mainframe.Models.AccountStorage, :__info__, 1, 1, 1}, {Mainframe.Models.AccountStorage, :__info__, 1, 2, 1}, {Mainframe.Models.AccountStorage, :__info__, 1, 3, 1}, {Mainframe.Models.AccountStorage, :__changeset__, 0, 1, 1}, {Mainframe.Models.AccountStorage, :__schema__, 1, 1, 1}, {Mainframe.Models.AccountStorage, :__schema__, 1, 2, 1}, {Mainframe.Models.AccountStorage, :__schema__, 1, 3, 1}, {Mainframe.Models.AccountStorage, :__schema__, 1, 4, 1}, {Mainframe.Models.AccountStorage, :__schema__, 1, 5, 1}, {Mainframe.Models.AccountStorage, :__schema__, 1, 6, 1}, {Mainframe.Models.AccountStorage, :__schema__, 1, 7, 1}, {Mainframe.Models.AccountStorage, :__schema__, 1, 8, 1}, {Mainframe.Models.AccountStorage, :__schema__, 1, 9, 1}, {Mainframe.Models.AccountStorage, :__schema__, 1, 10, 1}, {Mainframe.Models.AccountStorage, :__schema__, 1, 11, 1}, {Mainframe.Models.AccountStorage, :__schema__, 1, 12, 1}, {Mainframe.Models.AccountStorage, :__schema__, 1, 13, 1}, {Mainframe.Models.AccountStorage, :__schema__, 2, 1, 1}, {Mainframe.Models.AccountStorage, :__schema__, 2, 2, 1}, {Mainframe.Models.AccountStorage, :__schema__, 2, 3, 1}, {Mainframe.Models.AccountStorage, :__schema__, 2, 4, 1}, {Mainframe.Models.AccountStorage, :__schema__, 2, 5, 1}, {Mainframe.Models.AccountStorage, :__schema__, 2, 6, 1}, {Mainframe.Models.AccountStorage, :__schema__, 2, 7, 1}, {Mainframe.Models.AccountStorage, :__schema__, 2, 8, 1}, {Mainframe.Models.AccountStorage, :__schema__, 2, 9, 1}, {Mainframe.Models.AccountStorage, :__struct__, 0, 1, 1}, {Mainframe.Models.AccountStorage, :__struct__, 1, 1, 2}, {Mainframe.Models.AccountStorage, :get, 1, 1, 2}, {Mainframe.Models.AccountStorage, :get, 2, 1, 2}, {Mainframe.Models.AccountStorage, :get, 2, 2, 2}, {Mainframe.Models.AccountStorage, :set, 3, 1, 1}, {Mainframe.Models.AccountStorage, :set, 4, 1, 8}]})
    cover.erl:1584: :cover.do_compile_beam2/5
    cover.erl:1478: :cover.do_compile_beam/3
    (stdlib) lists.erl:1239: :lists.map/2
    (stdlib) lists.erl:1239: :lists.map/2
    cover.erl:2732: anonymous fn/2 in :cover.pmap_spawn/4

17:51:20.978 [error] Process #PID<0.288.0> raised an exception
** (ArgumentError) argument error
    (stdlib) :ets.insert(:cover_internal_clause_table, {Mainframe.Plug.Forwarded, [{Mainframe.Plug.Forwarded, :__info__, 1, 1, 1}, {Mainframe.Plug.Forwarded, :__info__, 1, 2, 1}, {Mainframe.Plug.Forwarded, :__info__, 1, 3, 1}, {Mainframe.Plug.Forwarded, :call, 2, 1, 7}, {Mainframe.Plug.Forwarded, :init, 1, 1, 1}, {Mainframe.Plug.Forwarded, :ip, 2, 1, 13}, {Mainframe.Plug.Forwarded, :scheme, 2, 1, 1}, {Mainframe.Plug.Forwarded, :scheme, 2, 2, 1}, {Mainframe.Plug.Forwarded, :scheme, 2, 3, 1}]})
    cover.erl:1584: :cover.do_compile_beam2/5
    cover.erl:1478: :cover.do_compile_beam/3
    (stdlib) lists.erl:1239: :lists.map/2
    (stdlib) lists.erl:1239: :lists.map/2
    cover.erl:2732: anonymous fn/2 in :cover.pmap_spawn/4


(...) - more in this vein

Replacing curl

I noticed your todos include replacing curl with an Elixir lib. I tried dropping in HTTPotion thinking it would be a quick fix. It turns out HTTPotion isn't sending MIME headers with the request body. Without the headers, Coveralls barfs up a 500. I briefly considered building the headers within excoveralls but that way lies madness.

I may poke at this a bit more later in the week; I just wanted to give you a heads-up.

coveralls.detail filtering does not work as documented

The docs say:

Also, displayed source code can be filtered by specifying arguments (it will be matched against the FILE column value).

But when you give a source file name it acts as if it was a test script:

$ mix coveralls.detail lib/stashex/parallel_jobs.ex                                                                                                                                                                                     (07-15 10:34)
lib/stashex/parallel_jobs.ex:1: warning: redefining module Stashex.ParallelJobs
lib/stashex/parallel_jobs.ex:8: warning: redefining module Stashex.ParallelJobs.State
lib/stashex/parallel_jobs.ex:142: warning: default arguments in run_job/3 are never used


Finished in 0.1 seconds (0.1s on load, 0.00s on tests)
0 tests, 0 failures

Randomized with seed 248648
----------------
COV    FILE                                        LINES RELEVANT   MISSED
  0.0% lib/mix/tasks/stashex.load_test.ex            188       58       58
 83.3% lib/stashex.ex                                 35        6        1
  0.0% lib/stashex/cache.ex                           61       15       15
 20.6% lib/stashex/cache_cleaner.ex                  103       34       27
  0.0% lib/stashex/cluster/dummy.ex                    8        0        0
  0.0% lib/stashex/cluster/ec2.ex                    136       23       23
 57.4% lib/stashex/cluster/server.ex                 192       54       23
100.0% lib/stashex/cluster/static.ex                  15        4        0
  0.0% lib/stashex/download.ex                       161       36       36
  0.0% lib/stashex/download_hub.ex                    50        8        8
  0.0% lib/stashex/endpoint.ex                        19        0        0
  0.0% lib/stashex/utils/http.ex                      39       10       10
 18.2% lib/stashex/utils/phoenix.ex                   58       11        9
  0.0% lib/stashex/utils/random.ex                    13        2        2
  0.0% web/controllers/cache_controller.ex            63       11       11
  0.0% web/controllers/info_controller.ex             19        2        2
  0.0% web/controllers/stashy_controller.ex           31        6        6
  0.0% web/router.ex                                  14        0        0
  0.0% web/views/error_view.ex                        17        1        1
  0.0% web/web.ex                                     48        1        1
[TOTAL]  17.4%
----------------

And when you give it the test script file, it runs the tests but does not show the detailed coverage informations:

$ mix coveralls.detail test/stashex/parallel_jobs_test.exs                                                                                                                                                                              (07-15 10:34)
....

Finished in 0.05 seconds (0.04s on load, 0.01s on tests)
4 tests, 0 failures

Randomized with seed 546053
----------------
COV    FILE                                        LINES RELEVANT   MISSED
  0.0% lib/mix/tasks/stashex.load_test.ex            188       58       58
 83.3% lib/stashex.ex                                 35        6        1
  0.0% lib/stashex/cache.ex                           61       15       15
 20.6% lib/stashex/cache_cleaner.ex                  103       34       27
  0.0% lib/stashex/cluster/dummy.ex                    8        0        0
  0.0% lib/stashex/cluster/ec2.ex                    136       23       23
 57.4% lib/stashex/cluster/server.ex                 192       54       23
100.0% lib/stashex/cluster/static.ex                  15        4        0
  0.0% lib/stashex/download.ex                       161       36       36
  0.0% lib/stashex/download_hub.ex                    50        8        8
  0.0% lib/stashex/endpoint.ex                        19        0        0
 87.2% lib/stashex/parallel_jobs.ex                  173       47        6
  0.0% lib/stashex/utils/http.ex                      39       10       10
 18.2% lib/stashex/utils/phoenix.ex                   58       11        9
  0.0% lib/stashex/utils/random.ex                    13        2        2
  0.0% web/controllers/cache_controller.ex            63       11       11
  0.0% web/controllers/info_controller.ex             19        2        2
  0.0% web/controllers/stashy_controller.ex           31        6        6
  0.0% web/router.ex                                  14        0        0
  0.0% web/views/error_view.ex                        17        1        1
  0.0% web/web.ex                                     48        1        1
[TOTAL]  27.4%
----------------

Umbrella projects do not report numbers overall

I am running this coverage tool on an umbrella project and each individual sub-project seems to report its numbers but if one sub-project of the umbrella is a dependent on another then overall numbers are incorrect.

Is there a way to support this already?

Exit with status 1 when coverage drops below a configurable threshold

It would be great to have Mix tasks like mix coveralls or mix coveralls.html to exit with status 1 when coverage drops below a user-defined level on local tasks. That would be useful to interrupt CI pipelines, for instance.

I'd be glad to help implement this. I took a quick look at the code and it seems most stats are totalled in the ExCoveralls.Local module. Seems like it would be easy to expose a function there that returns the totals, then use those to get the percentage on the mix task and exit with status 1 if it's below something defined in the coveralls.json file. On the other hand, it may be worth refactoring some of the calculations that go on in ExCoveralls.Local so they happen in ExCoveralls.Stats instead (with Local invoking those to compose output).

Let me know what you think the best approach is and I can take a stab at it!

FunctionClauseError when using meck

I have a test suite in which for some of the tests I mock a module called MyApp.MyProblematicModule using meck. I am trying to use ExCoveralls for that test suite, but I am failing to even get it running.

This is the error I am getting when I try to run mix coveralls:

Randomized with seed 857085
** (FunctionClauseError) no function clause matching in List.to_string/1
    (elixir) lib/list.ex:619: List.to_string(nil)
    lib/excoveralls/cover.ex:20: ExCoveralls.Cover.module_path/1
    lib/excoveralls/stats.ex:53: ExCoveralls.Stats.add_counts/4
    (elixir) lib/enum.ex:1623: Enum."-reduce/3-lists^foldl/2-0-"/3
    lib/excoveralls/stats.ex:28: ExCoveralls.Stats.report/1
    lib/excoveralls.ex:35: ExCoveralls.execute/2
    (mix) lib/mix/tasks/test.ex:244: Mix.Tasks.Test.run/1
    (mix) lib/mix/task.ex:296: Mix.Task.run_task/3
    lib/mix/tasks.ex:53: Mix.Tasks.Coveralls.do_run/2
    (mix) lib/mix/task.ex:296: Mix.Task.run_task/3
    (mix) lib/mix/cli.ex:58: Mix.CLI.run_task/2
    (elixir) lib/code.ex:363: Code.require_file/2

To debug this issue, I added those lines to my test_helper.exs:

ExCoveralls.Cover.modules |> Enum.each(fn module ->
  IO.inspect(module.module_info(:module))
  IO.inspect(module.module_info(:compile)[:source])
end)

I have found that there is a module called MyApp.MyProblematicModule_meck_original whose source is nil.

My Elixir version is 1.3.2 and my ExCoveralls version is 0.5.6.

Unable to see JSON with `--verbose`

โฏ MIX_ENV=test mix coveralls --help
-v (--verbose)      Show json string for posting.

When I use --verbose or -v I see the usual detail but no JSON.

MIX_ENV=test mix coveralls --verbose

.eex template error: no function clause matching in Enum.reverse_slice/3

coveralls 0.5.5 on Erlang/OTP 19 for mix coveralls.html results in:

** (FunctionClauseError) no function clause matching in Enum.reverse_slice/3
    (elixir) lib/enum.ex:1864: Enum.reverse_slice(["cldr.ex", "lib"], 1, #Function<3.4269533/1 in ExCoveralls.Html.View.render/1>)
    lib/templates/html/htmlcov/coverage.html.eex:17: anonymous fn/2 in ExCoveralls.Html.View.render/1

The offending line is in coverage.html.eex:

<% [b | s] = String.split(file.filename, "/") |> Enum.reverse |> Enum.reverse_slice(1, &(&1.length)) %>'

Here the code is calling Enum.reverse_slice(["path", "components"], 1, &(&1.length)) which doesn't make sense to me since the third argument should be a count which should be an integer. I assume the intent is to dynamically determine the length of the list in the first argument, but this code doesn't do that.

Possible fix

Change line 17 to:

<% parts = String.split(file.filename, "/") %>
<% [b | s] = parts |> Enum.reverse |> Enum.reverse_slice(1, Enum.count(parts))%>

This appears to work (in my system).

Empty clause not ignored

I'm getting a weird issue where an empty clause for a function with a default value and multiple clauses is considered "uncovered" by the library.

My code looks as follows.

  def verify(_, _, verifier \\ SomeVerifier)
  def verify(_signed_token, [], _verifier), do: {:error, :invalid_token_signature}
  def verify(signed_token, [public_key | rest], verifier) do
    try do
      case verifier.verify_strict(public_key, ["RS256"], signed_token) do
        {true, %{fields: claims}, _} -> {:ok, claims}
        _ -> verify(signed_token, rest, verifier)
      end
    rescue
      MatchError -> {:error, :invalid_token}
    end
  end

For some reason excoveralls thinks the first line isn't covered. I know I can work around the issue by using nested case statements or "indirecting" the recursive function by calling a private one (e.g. do_verify), but I prefer not to do any of that.

Any idea?

** (UndefinedFunctionError) undefined function: __info__/1

Hello,

I'm using excoveralls 0.4.0 with Elixir 1.1.1 and Erlang 18.1 under 64-bit Linux. ๐Ÿ˜ƒ

Following this guide, I created a src/Elixir.My.List.Lexer.xrl file containing:

Definitions.

INT        = [0-9]+
ATOM       = :[a-z_]+
WHITESPACE = [\s\t\n\r]

Rules.

{INT}         : {token, {int,  TokenLine, list_to_integer(TokenChars)}}.
{ATOM}        : {token, {atom, TokenLine, to_atom(TokenChars)}}.
\[            : {token, {'[',  TokenLine}}.
\]            : {token, {']',  TokenLine}}.
,             : {token, {',',  TokenLine}}.
{WHITESPACE}+ : skip_token.

Erlang code.

to_atom([$:|Chars]) ->
    list_to_atom(Chars).

Afterwards, I get the following error when running mix coveralls: ๐Ÿ˜ฑ

$ MIX_ENV=test mix coveralls
Compiled src/Elixir.My.List.Lexer.xrl
Compiled src/Elixir.My.List.Lexer.erl
...
72 tests, 0 failures

Randomized with seed 236840
** (UndefinedFunctionError) undefined function: My.List.Lexer.__info__/1
    (yield) My.List.Lexer.__info__(:compile)
    lib/excoveralls/cover.ex:19: ExCoveralls.Cover.module_path/1
    lib/excoveralls/stats.ex:36: ExCoveralls.Stats.add_counts/4
    (elixir) lib/enum.ex:1387: Enum."-reduce/3-lists^foldl/2-0-"/3
    lib/excoveralls/stats.ex:11: ExCoveralls.Stats.report/1
    lib/excoveralls.ex:29: ExCoveralls.execute/2
    (mix) lib/mix/tasks/test.ex:198: Mix.Tasks.Test.run/1
    lib/mix/tasks.ex:43: Mix.Tasks.Coveralls.do_run/2
    (mix) lib/mix/cli.ex:55: Mix.CLI.run_task/2
    (elixir) lib/code.ex:363: Code.require_file/2

exit 1

See also elixir-lang/ex_doc#453 ๐Ÿน

Thanks for your consideration.

Add documentation about defaulting to env :dev

Thanks for the great work here!

It may be worth documenting that the mix coveralls command doesn't run in the :test env by default. I mention this as I got some failing tests while running coveralls due to the :dev database having extra content.

Of course MIX_ENV=test mix coveralls is a very easy solution, but worth mentioning explicitly in the readme. As a beginner with elixir this would be very helpful.

Option to ignore files

It would be useful to be able to ignore specific files. For example files with macros or functions called at compile time.

The option could go into the coveralls.json. If you agree I can send a PR.

[Settings] coveralls.json

Hi,

Why didn't you use a dotfile for the coveralls.json?

I come from a ruby background and it seems like services like yours tend to use dotfile for their settings.

Thanks in advance for the answer.

Running `mix coveralls` task fails with unclean build director after source-file deletion

When running mix coveralls with a dirty build directory, one that contains beam files with missing source files, a File.Error is raised when ExCoveralls.Stats. get_source_line_count tries to count the lines of the missing source file. This is more likely with build caching set up in travis.

I would propose that these errors should be handled and displayed as either errors or warnings with a suggestion to clean any _build directories that are being checked.

I'm also guessing that this would happen anywhere read_source is called.

Error when running on Erlang 19.0 / Elixir 1.3.3

The coverage outputs fine but there is some kind of error in the ensure_minimum_coverage function.

Finished in 1.3 seconds
28 tests, 0 failures

Randomized with seed 231376
----------------
COV    FILE                                        LINES RELEVANT   MISSED
 84.9% lib/tally.ex                                  359      119       18
 80.0% lib/tally/application.ex                       29        5        1
  0.0% lib/tally/external/exchange_rates.ex           11        1        1
 60.0% lib/tally/handlers/event_handler.ex            40       15        6
 88.7% lib/tally/liability.ex                        157       53        6
  0.0% lib/tally/message/fraction.ex                  17        1        1
  0.0% lib/tally/message/keywords.ex                  19        1        1
  0.0% lib/tally/message/placement.ex                 45        1        1
  0.0% lib/tally/message/placement/selections.e       47        1        1
100.0% lib/tally/message/placement/subselection       20        1        0
  0.0% lib/tally/message/settlement.ex                67        1        1
  0.0% lib/tally/message/settlement/selections.       49        1        1
100.0% lib/tally/message/settlement/subselectio       16        1        0
 16.7% lib/tally/placement_receiver.ex                32        6        5
  0.0% lib/tally/settlement_receiver.ex               31        6        6
100.0% lib/tally/structures/id.ex                     14        1        0
  0.0% lib/tally/structures/meta.ex                   12        1        1
100.0% lib/tally/structures/tally.ex                  21        1        0
  0.0% lib/tally/structures/update.ex                 21        1        1
100.0% lib/tally/supervisor.ex                        22        2        0
 85.7% test/support/tally/producer/backend/test       42        7        1
100.0% test/support/tally/tally.ex                     5        1        0
100.0% test/support/tally/telemetry/telemetry.e       22        6        0
 88.9% test/support/tally/telemetry/telemetry/s       41        9        1
[TOTAL]  78.1%
----------------
** (Protocol.UndefinedError) protocol Enumerable not implemented for nil
    (elixir) lib/enum.ex:1: Enumerable.impl_for!/1
    (elixir) lib/enum.ex:116: Enumerable.reduce/3
    (elixir) lib/enum.ex:1636: Enum.reduce/3
    lib/excoveralls/stats.ex:209: ExCoveralls.Stats.ensure_minimum_coverage/1
    (mix) lib/mix/tasks/test.ex:244: Mix.Tasks.Test.run/1
    (mix) lib/mix/task.ex:296: Mix.Task.run_task/3
    lib/mix/tasks.ex:53: Mix.Tasks.Coveralls.do_run/2
    (mix) lib/mix/task.ex:296: Mix.Task.run_task/3
    (mix) lib/mix/cli.ex:58: Mix.CLI.run_task/2
    (elixir) lib/code.ex:363: Code.require_file/2

I can't seem to find where it is coming from.

--include tags

My test helper has the following line to exclude tests that hit remote services by default:

ExUnit.configure(exclude: [:remote])

When I want remote tests I run:

mix test --include remote

What is the equivalent for mix coveralls?

hex package 0.2.3 has invalid version inside

Hi!

Versions not synced - hex package 0.2.3 has version 0.2.4 inside in mix.exs, preventing it from being installed.
Can you please publish other version or republish that old one with content fixed? TIA

0% coverage for 0 missed lines

Hello,

I'm using Elixir 1.1.1 with Erlang 18.1 and ExCoveralls 0.3.11 under 64-bit Linux.

The problem is that 0% coverage is reported for a file with 0 missed lines: ๐Ÿ˜ฑ

COV    FILE                                        LINES RELEVANT   MISSED
  0.0% lib/-----------------------------.ex           40        0        0

Shouldn't this be 100% coverage? ๐Ÿ˜ฐ

Thanks for your consideration.

Ability to configure how output is sorted.

Hi

I am using this project to output html which I view in the browser.
I would like to see the output sorted by coverage percentage rather than by name.

I have looked at various ways to achieve this, from sorting in javascript, to sorting in eex in the html template to sorting in ExCoveralls.Stats.

It makes sense to me that you should be able to configure this as a setting in the json file.

Do you have thoughts on what the best approach would be? Have you considered this and decided against it or has it just not come up?

Coverage changes when running coveralls vs coveralls.html

First off, thank you for making such a sweet coverage tool! I'd love to find out why my tests are differing based on how I run them. Here's what's happening.

The coverage seems to change based on whether I run mix coveralls or mix coveralls.html. There are no code changes between these two test runs.

This also seems to incorrectly identify as not covered.
schema "project_update_reports" do ... end

When I run MIX_ENV=test mix coveralls

Randomized with seed 163131
----------------
COV    FILE                                        LINES RELEVANT   MISSED
100.0% web/controllers/project_controller.ex          27        4        0
100.0% web/models/client.ex                           23        2        0
100.0% web/models/project.ex                          28        2        0
100.0% web/models/project_service.ex                  21        3        0
100.0% web/models/project_service_link.ex             20        2        0
100.0% web/models/project_update.ex                   21        2        0
 50.0% web/models/project_update_report.ex            21        2        1
100.0% web/models/role.ex                             21        2        0
100.0% web/models/user.ex                             24        3        0
100.0% web/router.ex                                  57        2        0
100.0% web/uploaders/avatar.ex                        32        3        0
100.0% web/uploaders/icon.ex                          32        3        0
[TOTAL]  96.7%

When I runMIX_ENV=test mix coveralls.html

Randomized with seed 345244
----------------
COV    FILE                                        LINES RELEVANT   MISSED
100.0% web/controllers/project_controller.ex          27        4        0
100.0% web/models/client.ex                           23        2        0
100.0% web/models/project.ex                          28        2        0
100.0% web/models/project_service.ex                  21        3        0
 50.0% web/models/project_service_link.ex             20        2        1
 50.0% web/models/project_update.ex                   21        2        1
 50.0% web/models/project_update_report.ex            21        2        1
100.0% web/models/role.ex                             21        2        0
 66.7% web/models/user.ex                             24        3        1
100.0% web/router.ex                                  57        2        0
100.0% web/uploaders/avatar.ex                        32        3        0
100.0% web/uploaders/icon.ex                          32        3        0
[TOTAL]  86.7%

mix coveralls.circle fails

Randomized with seed 210845
Successfully uploaded the report to 'https://coveralls.io'.
** (exit) an exception was raised:
    ** (ArgumentError) argument error
        (stdlib) erl_anno.erl:318: :erl_anno.set(:location, -1, [location: -1, generated: true])
        (stdlib) erl_parse.yrl:1516: anonymous fn/3 in :erl_parse.map_anno/2
        (stdlib) erl_parse.yrl:1645: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1637: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1659: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1648: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1659: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1637: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1659: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1648: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1648: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1517: :erl_parse.map_anno/2
        (stdlib) epp.erl:1698: :epp.interpret_file_attr/3
        (stdlib) epp.erl:1699: :epp.interpret_file_attr/3
        (stdlib) epp.erl:1690: :epp.interpret_file_attr/3
    cover.erl:583: :cover.call/1
    lib/excoveralls.ex:30: ExCoveralls.start/2
    (mix) lib/mix/tasks/test.ex:205: Mix.Tasks.Test.run/1
    (mix) lib/mix/task.ex:296: Mix.Task.run_task/3
    (mix) lib/mix/project.ex:211: Mix.Project.in_project/4
    (elixir) lib/file.ex:1145: File.cd!/2
    (mix) lib/mix/task.ex:387: anonymous fn/4 in Mix.Task.recur/1
    (elixir) lib/enum.ex:1623: Enum."-reduce/3-lists^foldl/2-0-"/3
    (mix) lib/mix/task.ex:386: Mix.Task.recur/1
    (mix) lib/mix/project_stack.ex:135: Mix.ProjectStack.recur/1
    (mix) lib/mix/task.ex:328: Mix.Task.run_alias/3
    (mix) lib/mix/task.ex:261: Mix.Task.run/2
    lib/mix/tasks.ex:53: Mix.Tasks.Coveralls.do_run/2
    (mix) lib/mix/task.ex:296: Mix.Task.run_task/3
    (mix) lib/mix/cli.ex:58: Mix.CLI.run_task/2
    (elixir) lib/code.ex:363: Code.require_file/2

version from iex

Erlang/OTP 19 [erts-8.1] [source] [64-bit] [smp:32:2] [async-threads:10] [hipe] [kernel-poll:false]

Interactive Elixir (1.3.3) - press Ctrl+C to exit (type h() ENTER for help)

Error when changing app env in run-time

mix coveralls

18:33:13.984 [error] Process #PID<0.265.0> raised an exception
** (ArgumentError) argument error
    (stdlib) erl_anno.erl:318: :erl_anno.set(:location, -1, [location: -1, generated: true])
    (stdlib) erl_parse.yrl:1516: anonymous fn/3 in :erl_parse.map_anno/2
    (stdlib) erl_parse.yrl:1645: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1637: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1652: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1648: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1648: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1517: :erl_parse.map_anno/2
    (stdlib) epp.erl:1698: :epp.interpret_file_attr/3
    (stdlib) epp.erl:1699: :epp.interpret_file_attr/3
    (stdlib) epp.erl:1690: :epp.interpret_file_attr/3
    (stdlib) epp.erl:1699: :epp.interpret_file_attr/3
    cover.erl:1545: :cover.do_compile_beam1/3
    cover.erl:1478: :cover.do_compile_beam/3
    (stdlib) lists.erl:1239: :lists.map/2
    cover.erl:2732: anonymous fn/2 in :cover.pmap_spawn/4
** (exit) an exception was raised:
    ** (ArgumentError) argument error
        (stdlib) erl_anno.erl:318: :erl_anno.set(:location, -1, [location: -1, generated: true])
        (stdlib) erl_parse.yrl:1516: anonymous fn/3 in :erl_parse.map_anno/2
        (stdlib) erl_parse.yrl:1645: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1637: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1652: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1648: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1648: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1517: :erl_parse.map_anno/2
        (stdlib) epp.erl:1698: :epp.interpret_file_attr/3
        (stdlib) epp.erl:1699: :epp.interpret_file_attr/3
        (stdlib) epp.erl:1690: :epp.interpret_file_attr/3
        (stdlib) epp.erl:1699: :epp.interpret_file_attr/3
        cover.erl:1545: :cover.do_compile_beam1/3
        cover.erl:1478: :cover.do_compile_beam/3
        (stdlib) lists.erl:1239: :lists.map/2
        cover.erl:2732: anonymous fn/2 in :cover.pmap_spawn/4
    cover.erl:583: :cover.call/1
    lib/excoveralls.ex:28: ExCoveralls.start/2
    (mix) lib/mix/tasks/test.ex:205: Mix.Tasks.Test.run/1
    (mix) lib/mix/task.ex:296: Mix.Task.run_task/3
    (mix) lib/mix/task.ex:328: Mix.Task.run_alias/3
    (mix) lib/mix/task.ex:261: Mix.Task.run/2
    lib/mix/tasks.ex:53: Mix.Tasks.Coveralls.do_run/2
    (mix) lib/mix/task.ex:296: Mix.Task.run_task/3
    (mix) lib/mix/cli.ex:58: Mix.CLI.run_task/2
    (elixir) lib/code.ex:363: Code.require_file/2


18:33:13.987 [error] Process #PID<0.262.0> raised an exception
** (ArgumentError) argument error
    (stdlib) :ets.insert(:cover_internal_data_table, {{:bump, AssetProcessor.API, :config_change, 3, 1, 43}, 0})
    cover.erl:1789: :cover.munge_body/4
    cover.erl:1740: :cover.munge_clauses/4
    cover.erl:1719: :cover.munge/4
    cover.erl:1635: :cover.transform_2/5
    cover.erl:1620: :cover.transform/3
    cover.erl:1568: :cover.do_compile_beam2/5
    cover.erl:1478: :cover.do_compile_beam/3
    (stdlib) lists.erl:1239: :lists.map/2
    cover.erl:2732: anonymous fn/2 in :cover.pmap_spawn/4

18:33:13.987 [error] Process #PID<0.264.0> raised an exception
** (ArgumentError) argument error
    (stdlib) :ets.insert(:cover_internal_data_table, {{:bump, AssetProcessor.API.ErrorView, :render, 2, 1, 7}, 0})
    cover.erl:1789: :cover.munge_body/4
    cover.erl:1740: :cover.munge_clauses/4
    cover.erl:1719: :cover.munge/4
    cover.erl:1635: :cover.transform_2/5
    cover.erl:1620: :cover.transform/3
    cover.erl:1568: :cover.do_compile_beam2/5
    cover.erl:1478: :cover.do_compile_beam/3
    (stdlib) lists.erl:1239: :lists.map/2
    cover.erl:2732: anonymous fn/2 in :cover.pmap_spawn/4

18:33:13.988 [error] Process #PID<0.266.0> raised an exception
** (ArgumentError) argument error
    (stdlib) :ets.insert(:cover_internal_data_table, {{:bump, AssetProcessor.API.Validators.BatchUpload, :__info__, 1, 1, 0}, 0})
    cover.erl:1789: :cover.munge_body/4
    cover.erl:1740: :cover.munge_clauses/4
    cover.erl:1719: :cover.munge/4
    cover.erl:1635: :cover.transform_2/5
    cover.erl:1620: :cover.transform/3
    cover.erl:1568: :cover.do_compile_beam2/5
    cover.erl:1478: :cover.do_compile_beam/3
    (stdlib) lists.erl:1239: :lists.map/2
    cover.erl:2732: anonymous fn/2 in :cover.pmap_spawn/4

18:33:13.988 [error] Process #PID<0.263.0> raised an exception
** (ArgumentError) argument error
    (stdlib) erl_anno.erl:318: :erl_anno.set(:location, -1, [location: -1, generated: true])
    (stdlib) erl_parse.yrl:1516: anonymous fn/3 in :erl_parse.map_anno/2
    (stdlib) erl_parse.yrl:1645: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1637: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1659: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1648: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1648: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1517: :erl_parse.map_anno/2
    (stdlib) epp.erl:1698: :epp.interpret_file_attr/3
    (stdlib) epp.erl:1699: :epp.interpret_file_attr/3
    (stdlib) epp.erl:1690: :epp.interpret_file_attr/3
    (stdlib) epp.erl:1699: :epp.interpret_file_attr/3
    cover.erl:1545: :cover.do_compile_beam1/3
    cover.erl:1478: :cover.do_compile_beam/3
    (stdlib) lists.erl:1239: :lists.map/2
    cover.erl:2732: anonymous fn/2 in :cover.pmap_spawn/4

Argument error when running mix coveralls on project

Thanks for the great library, we've pulled it into our project and are planning to use it as a measure of code quality. Particularly love the HTML output.

One issue we've run into, after running mix coveralls for the first time in a while (it was working fine a week ago). I'll post the error we are seeing then give some background:

16:01:10.683 [error] Process #PID<0.4704.0> raised an exception
** (ArgumentError) argument error
    (stdlib) erl_anno.erl:318: :erl_anno.set(:location, -1, [location: -1, generated: true])
    (stdlib) erl_parse.yrl:1516: anonymous fn/3 in :erl_parse.map_anno/2
    (stdlib) erl_parse.yrl:1645: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1637: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1648: :erl_parse.modify_anno1/3
    (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
** (exit) an exception was raised:
    ** (ArgumentError) argument error
        (stdlib) erl_anno.erl:318: :erl_anno.set(:location, -1, [location: -1, generated: true])
        (stdlib) erl_parse.yrl:1516: anonymous fn/3 in :erl_parse.map_anno/2
        (stdlib) erl_parse.yrl:1645: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1637: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1648: :erl_parse.modify_anno1/3
        (stdlib) erl_parse.yrl:1658: :erl_parse.modify_anno1/3
    cover.erl:583: :cover.call/1
    lib/excoveralls.ex:28: ExCoveralls.start/2
    (mix) lib/mix/tasks/test.ex:193: Mix.Tasks.Test.run/1
    (mix) lib/mix/task.ex:296: Mix.Task.run_task/3
    lib/mix/tasks.ex:47: Mix.Tasks.Coveralls.do_run/2
    (mix) lib/mix/task.ex:296: Mix.Task.run_task/3
    (mix) lib/mix/cli.ex:58: Mix.CLI.run_task/2

Now, we are using the latest version 0.5.5 of ExCoveralls (from Hex). It's on Elixir 1.3.1, and Erlang/OTP 19.

Having done a bit of investigation it seems like things are going wrong at the point of :cover.compile_beam_directory(compile_path |> to_char_list) in cover.ex. The path to our beam files seems to be okay (_build/test/lib/<our_project>/ebin) but yet the error above is presented.

Our setup is very vanilla in terms of pulling ExCoveralls through Hex, and configuring the deps just as shown in the readme:

test_coverage: [tool: ExCoveralls],
     preferred_cli_env: ["coveralls": :test, "coveralls.detail": :test, "coveralls.html": :test, "coveralls.post": :test]

Have you seen anything like this? Any help would be great.

excoveralls doesn't compile on Elixir 1.1

I'm trying to run sugar with elixir 1.1 and it's failing to compile excoveralls. Here's the error I get when I compile excoveralls by itself.

It would be great if excoveralls worked for the latest version of elixir.

mdg@host:~/src/check/deps/excoveralls$ mix compile
** (Mix) You're trying to run :excoveralls on Elixir v1.1.0-dev but it has declared in its mix.exs file it supports only Elixir ~> 0.13.1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.