1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//! Language-independent source code metrics.
//!
//! `srcmetrics` parses source code with [tree-sitter](https://tree-sitter.github.io/), converts it
//! to a small language-independent intermediate representation ([`ir`]), and computes metrics
//! from that representation only ([`metrics`]). Every metric is reported separately under its id
//! ([`metrics::specs`]); none are combined into a single readability score. What each metric means
//! is documented at <https://lunainsidious.github.io/srcmetrics/metrics/>.
//!
//! Supported languages: C, C++, Go, Java, JavaScript (JSX), Python, Rust, TypeScript (TSX).
//!
//! # Analyze source text
//!
//! ```
//! let result = srcmetrics::analyze::analyze_source(
//! "example.py",
//! "def greet(name):\n if name:\n return 'Hello, ' + name\n return 'Hello'\n",
//! )?;
//! let srcmetrics::result::FileResult::Ok { functions, .. } = &result.files[0] else { unreachable!() };
//! assert_eq!(functions[0].name.as_deref(), Some("greet"));
//! assert_eq!(functions[0].metrics.metrics["complexity.cyclomatic"], Some(2.0));
//! # Ok::<(), srcmetrics::error::AnalysisError>(())
//! ```
//!
//! # Analyze a directory
//!
//! [`analyze::analyze`] walks a directory (respecting `.gitignore`), analyzes every file with a
//! supported extension and records run metadata (commit, parser and metric definition versions).
//! Files that fail to parse are kept in the result with `status: "error"` instead of being dropped.
//!
//! ```no_run
//! let result = srcmetrics::analyze::analyze(std::path::Path::new("src"), None)?;
//! println!("{}", serde_json::to_string_pretty(&result).unwrap());
//! # Ok::<(), srcmetrics::error::AnalysisError>(())
//! ```
//!
//! A metric that cannot be computed (e.g. an average over zero functions) is `null` in
//! [`result::MetricsOutput::metrics`], with the reason in [`result::MetricsOutput::unavailable`];
//! it is never reported as 0.