{"id":25595387,"url":"https://github.com/inaka/xref_runner","last_synced_at":"2025-03-17T15:13:45.169Z","repository":{"id":26958546,"uuid":"30421608","full_name":"inaka/xref_runner","owner":"inaka","description":"Erlang Xref Runner (inspired in rebar xref)","archived":false,"fork":false,"pushed_at":"2023-06-27T06:10:59.000Z","size":232,"stargazers_count":50,"open_issues_count":1,"forks_count":16,"subscribers_count":41,"default_branch":"master","last_synced_at":"2025-03-02T13:10:03.243Z","etag":null,"topics":["erlang","hacktoberfest","rebar-xref","xref","xref-runner"],"latest_commit_sha":null,"homepage":"http://inaka.github.io/xref_runner","language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/inaka.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-02-06T16:31:58.000Z","updated_at":"2023-09-26T06:12:35.000Z","dependencies_parsed_at":"2023-02-10T03:30:43.377Z","dependency_job_id":null,"html_url":"https://github.com/inaka/xref_runner","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inaka%2Fxref_runner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inaka%2Fxref_runner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inaka%2Fxref_runner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/inaka%2Fxref_runner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/inaka","download_url":"https://codeload.github.com/inaka/xref_runner/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244056424,"owners_count":20390719,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["erlang","hacktoberfest","rebar-xref","xref","xref-runner"],"created_at":"2025-02-21T11:20:43.072Z","updated_at":"2025-03-17T15:13:45.127Z","avatar_url":"https://github.com/inaka.png","language":"Erlang","funding_links":[],"categories":[],"sub_categories":[],"readme":"![](https://twistedsifter.files.wordpress.com/2015/03/wile-e-coyote-chasing-the-road-runner.jpg)\n\n# Xref Runner\nErlang Xref Runner (inspired by rebar's rebar_xref)\n\n## Contact Us\nIf you find any **bugs** or have a **problem** while using this library, please\n[open an issue](https://github.com/inaka/elvis/issues/new) in this repo\n(or a pull request :)).\n\nAnd you can check all of our open-source projects at [inaka.github.io](http://inaka.github.io).\n\n## Why Xref Runner?\nSo, Erlang/OTP comes with an excellent tool to check your code and detect bugs: [Xref](http://www.erlang.org/doc/apps/tools/xref_chapter.html).\nThe problem lies in its not-extremely-simple interface. Using `xref` out of the box requires you to start a process, set up parameters, add directories, etc. before you can actually just run the checks you want to run.\nTo mitigate that, [rebar](http://github.com/rebar/rebar) comes with a handy command line tool (`rebar xref`) that prints xref generated warnings on your console.\nBut, sometimes, you don't want to use rebar or you want to get the warnings as erlang terms and not just printed out in the console.\nThat's when xref_runner comes along.\n\n### Script\n\n`xref_runner` can be turned into a script by executing `rebar3 escriptize`. This will\ngenerate a self-contained executable script in `_build/default/bin/xrefr`, from which\nyou can get help by typing `xrefr -h`.\n\nUse `xrefr` command to run from the terminal (i.e. `xrefr`).\nThere's no need to specify a configuration file path if you have an\n`xref.config` file in the same location where you are executing the script,\notherwise a configuration file can be specified through the use of the\n`--config` (or just `-c`) option.\n\n```bash\nxrefr --config xref.config\n```\n\n## How to Use it?\nJust make sure it's in your code path and call `xref_runner:check/2` with the proper parameters.\n\nThe first parameter is one of the available checks provided by `xref`:\n```erlang\n-type check() :: undefined_function_calls\n               | undefined_functions\n               | locals_not_used\n               | exports_not_used\n               | deprecated_function_calls\n               | deprecated_functions.\n```\n\nThe second paramter is a configuration map. All of its fields are optional. The allowed fields are:\n\n* **extra_paths**: Directories to be added to the xref code path. _default value:_ `[]`\n* **xref_defaults**: Default values to configure xref (check `xref:set_default`). _default value:_ `[]`\n* **dirs**: Directories to be scanned with `xref`. _default value:_ `[\"ebin\"]`\n\nAlso you can use `xref_runner:check/0` without parameters to run the whole check list. In this case, the configuration will be taken from `xref.config` from the root dir, that should look like this:\n```erlang\n[\n   {xref, [\n            {config, #{dirs =\u003e [\"test\"]}},\n            {checks, [ undefined_function_calls\n                     , undefined_functions\n                     , locals_not_used\n                     , exports_not_used\n                     , deprecated_function_calls\n                     , deprecated_functions\n                     ]}\n          ]\n   }\n].\n```\n\nUsing that function will give you a list of _warnings_ as its result. Warnings are also maps with the following fields:\n\n* **filename**: The name of the file for which the warning is reported\n* **line**: The line number where the warning is reported. `0` means it's a module-level warning (like an undefined function). _Note:_ In case of warnings with source and target, line numbers refer to the line in which the source function is _defined_, not the line where the target function is _used_.\n* **source**: Module, function and argument number where the warning is found\n* **target** _(optional)_: For `undefined_function_calls` and `deprecated_function_calls`, function call that generates the warning.\n\n## Examples\nUsing the modules in the [examples](test/examples) folder, these are some of the results generated by the tests:\n\n```erlang\n\u003e xref_runner:check(undefined_function_calls, #{dirs =\u003e [\"test\"]}).\n[#{check =\u003e undefined_function_calls,\n   filename =\u003e \"test/examples/undefined_function_calls.erl\",\n   line =\u003e 5,\n   source =\u003e {undefined_function_calls,bad,0},\n   target =\u003e {undefined_function_calls,undefined_here,0}},\n #{check =\u003e undefined_function_calls,\n   filename =\u003e \"test/examples/undefined_function_calls.erl\",\n   line =\u003e 9,\n   source =\u003e {undefined_function_calls,bad,1},\n   target =\u003e {other_module,undefined_somewhere_else,1}},\n #{check =\u003e undefined_function_calls,\n   filename =\u003e \"test/examples/undefined_function_calls.erl\",\n   line =\u003e 9,\n   source =\u003e {undefined_function_calls,bad,1},\n   target =\u003e {undefined_functions,undefined_there,0}},\n …\n]\n```\n\n```erlang\n\u003e xref_runner:check(undefined_functions, #{dirs =\u003e [\"test\"],\n                                           xref_defaults =\u003e []}).\n[#{check =\u003e undefined_functions,\n   filename =\u003e [],\n   line =\u003e 0,\n   source =\u003e {other_module,undefined_somewhere_else,0}},\n #{check =\u003e undefined_functions,\n   filename =\u003e [],\n   line =\u003e 0,\n   source =\u003e {other_module,undefined_somewhere_else,1}},\n #{check =\u003e undefined_functions,\n   filename =\u003e \"test/examples/undefined_function_calls.erl\",\n   line =\u003e 0,\n   source =\u003e {undefined_function_calls,undefined_here,0}},\n …\n]\n```\n\n```erlang\n\u003e xref_runner:check(locals_not_used, #{dirs =\u003e [\"test\"]}).\n[#{check =\u003e locals_not_used,\n   filename =\u003e \"test/examples/locals_not_used.erl\",\n   line =\u003e 9,\n   source =\u003e {locals_not_used,local_not,1}}]\n```\n\n```erlang\n\u003e xref_runner:check(exports_not_used, #{dirs =\u003e [\"test\"]}).\n[#{check =\u003e exports_not_used,\n   filename =\u003e \"test/examples/deprecated_function_calls.erl\",\n   line =\u003e 7,\n   source =\u003e {deprecated_function_calls,bad,0}},\n #{check =\u003e exports_not_used,\n   filename =\u003e \"test/examples/deprecated_function_calls.erl\",\n   line =\u003e 10,\n   source =\u003e {deprecated_function_calls,bad,1}},\n #{check =\u003e exports_not_used,\n   filename =\u003e \"test/examples/deprecated_function_calls.erl\",\n   line =\u003e 14,\n   source =\u003e {deprecated_function_calls,good,0}},\n…\n]\n```\n\n```erlang\n\u003e xref_runner:check(deprecated_function_calls, #{dirs =\u003e [\"test\"]}).\n[#{check =\u003e deprecated_function_calls,\n   filename =\u003e \"test/examples/deprecated_function_calls.erl\",\n   line =\u003e 7,\n   source =\u003e {deprecated_function_calls,bad,0},\n   target =\u003e {deprecated_functions,deprecated,0}},\n #{check =\u003e deprecated_function_calls,\n   filename =\u003e \"test/examples/deprecated_function_calls.erl\",\n   line =\u003e 10,\n   source =\u003e {deprecated_function_calls,bad,1},\n   target =\u003e {deprecated_function_calls,internal,0}},\n #{check =\u003e deprecated_function_calls,\n   filename =\u003e \"test/examples/deprecated_function_calls.erl\",\n   line =\u003e 10,\n   source =\u003e {deprecated_function_calls,bad,1},\n   target =\u003e {deprecated_functions,deprecated,1}},\n …\n]\n```\n\n```erlang\n\u003e xref_runner:check(deprecated_functions, #{dirs =\u003e [\"test\"]}).\n[#{check =\u003e deprecated_functions,\n   filename =\u003e \"test/examples/deprecated_function_calls.erl\",\n   line =\u003e 17,\n   source =\u003e {deprecated_function_calls,internal,0}},\n #{check =\u003e deprecated_functions,\n   filename =\u003e \"test/examples/deprecated_functions.erl\",\n   line =\u003e 8,\n   source =\u003e {deprecated_functions,deprecated,0}},\n #{check =\u003e deprecated_functions,\n   filename =\u003e \"test/examples/deprecated_functions.erl\",\n   line =\u003e 10,\n   source =\u003e {deprecated_functions,deprecated,1}},\n #{check =\u003e deprecated_functions,\n   filename =\u003e \"test/examples/ignore_xref.erl\",\n   line =\u003e 19,\n   source =\u003e {ignore_xref,internal,0}}]\n```\n\n```erlang\n\u003e xref_runner:check(deprecated_function_calls, #{dirs =\u003e [\"test\"]}).\n[#{check =\u003e deprecated_function_calls,\n   filename =\u003e \"test/examples/deprecated_function_calls.erl\",\n   line =\u003e 7,\n   source =\u003e {deprecated_function_calls,bad,0},\n   target =\u003e {deprecated_functions,deprecated,0}},\n #{check =\u003e deprecated_function_calls,\n   filename =\u003e \"test/examples/deprecated_function_calls.erl\",\n   line =\u003e 10,\n   source =\u003e {deprecated_function_calls,bad,1},\n   target =\u003e {deprecated_function_calls,internal,0}},\n #{check =\u003e deprecated_function_calls,\n   filename =\u003e \"test/examples/deprecated_function_calls.erl\",\n   line =\u003e 10,\n   source =\u003e {deprecated_function_calls,bad,1},\n   target =\u003e {deprecated_functions,deprecated,1}},\n …\n]\n```\n```erlang\n\u003e xref_runner:check().\n[#{check =\u003e undefined_function_calls,\n   filename =\u003e \"test/examples/undefined_function_calls.erl\",\n   line =\u003e 5,\n   source =\u003e {undefined_function_calls,bad,0},\n   target =\u003e {undefined_function_calls,undefined_here,0}},\n #{check =\u003e undefined_function_calls,\n   filename =\u003e \"test/examples/undefined_function_calls.erl\",\n   line =\u003e 9,\n   source =\u003e {undefined_function_calls,bad,1},\n   target =\u003e {other_module,undefined_somewhere_else,1}},\n #{check =\u003e undefined_function_calls,\n   filename =\u003e \"test/examples/undefined_function_calls.erl\",\n   line =\u003e 9,\n   source =\u003e {undefined_function_calls,bad,1},\n   target =\u003e {undefined_functions,undefined_there,0}},\n…\n]\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finaka%2Fxref_runner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finaka%2Fxref_runner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finaka%2Fxref_runner/lists"}