How aserg-ufmg/truck-factor works
1. What this repository is
- This is a Java-based analysis tool, not the target project itself. It estimates a GitHub repository’s Truck Factor from commit history and file authorship data.
- The system is built as a pipeline: extract repository metadata, persist it, compute authorship/ownership metrics, then calculate Truck Factor.
2. Top-level execution model
- The README describes a three-step flow:
1. Build the Java artifact with Maven.
2. Run shell/AWK/Ruby scripts against the repository being analyzed to extract commit and file information.
3. Execute the generated JAR with the target repo path and its full GitHub name.
- This separation creates a clear boundary between the analyzer repo (gittruckfactor) and the analyzed repo (any Git project on disk).
3. Entry points and orchestration
- aserg.gtf.GitTruckFactor and GitTruckFactorRepList are the main Java entry points.
- task.AbstractTask and the classes under task/ coordinate the stages of the analysis, likely loading config, invoking extractors, handling aliases, and triggering Truck Factor calculation.
4. Repository extraction layer
- task/extractor/GitLogExtractor works with the commit history output generated by scripts/commit_log_script.sh.
- task/extractor/FileInfoExtractor and task/extractor/LinguistExtractor handle file-level metadata and optional file filtering.
- The extraction boundary is externalized into scripts (commit_log_script.sh, linguist_script.sh, log.awk, linguist.rb), which means the Java code consumes preprocessed artifacts rather than querying git directly in-process.
5. Optional preprocessing and repo-specific overrides
- The repo_info/ directory provides repository-specific tuning inputs:
- filtered-files.txt for excluding files,
- alias.txt for merging developer aliases,
- modules.txt for module mapping.
- The README notes that module calculation is not implemented yet, so that file is currently metadata support rather than a full subsystem.
6. Authorship and ownership domain model
- The model/authorship package contains the core entities for code ownership analysis:
- Developer, File, Repository,
- AuthorshipInfo, DeveloperAuthorshipInfo,
- status/enumeration classes such as DevStatus and RepositoryStatus.
- This model represents the intermediate state used to derive who “owns” which files and how strongly.
7. General persistence and data access
- The dao/ package is a classic data-access layer with a generic DAO base and entity-specific DAOs such as CommitInfoDAO, CommitFileDAO, ProjectInfoDAO, and GitRepositoryDAO.
- PersistThread suggests persistence can happen asynchronously or in a buffered/background mode.
- JPA is configured through META-INF/persistence.xml, so the analysis state is persisted via a JPA-backed storage layer rather than kept only in memory.
8. Truck Factor computation
- The truckfactor/ package holds the algorithmic core:
- TruckFactor is the abstraction,
- GreedyTruckFactor and PrunedGreedyTruckFactor are concrete strategies,
- TFInfo likely packages the computed result and related metadata.
- This is the final analysis stage: using authorship/DOA data to determine the minimum number of critical developers whose loss would threaten project maintainability.
9. DOA and alias handling
- task/DOACalculator computes Degree of Authorship, which is an intermediate metric feeding ownership and Truck Factor logic.
- task/AliasHandler and NewAliasHandler normalize developer identities using alias information, which is important because commit histories often contain multiple names/emails for the same person.
- util/AliasesIdentifier and util/Alias support this identity resolution.
10. Utility and parsing infrastructure
- The util/ package contains low-level helpers for file reading, directory traversal, formatting, and line parsing.
- Classes like CRLFLineReader, FileInfoReader, Directory, FileDirectory, and LineInfo indicate the tool processes text artifacts generated from git history and file scans.
- FormatDoaDistribution suggests the tool also formats or reports the DOA distribution used by the truck factor calculation.
11. Runtime, build, and deployment boundaries
- The project is a Maven Java application under gittruckfactor/.
- Docker support is present via compose.yml, .env, and the .docker/linguist image, mainly to standardize execution of the script-based preprocessing and optional Linguist filtering.
- The README explicitly notes that the analyzed repository path is configured via .env when using Docker.
12. Important architectural shape for a diagram
- Draw it as a left-to-right pipeline:
- analyzed Git repository
- shell/AWK/Ruby extraction scripts
- Java extractors/tasks
- DAO/JPA persistence and domain models
- DOA/authorship computation
- Truck Factor algorithm
- final TF output
- The main boundary to highlight is that the tool consumes external git data and repo-specific override files, then converts them into persisted domain objects and algorithm inputs before computing the final metric.
Main entry points: AbstractTask.java Task base · Repository.java Authorship model · TruckFactor.java TF core · FileInfoExtractor.java File info
Components 21
External Inputs
Analyzed repository plus preprocessing scripts and repo-specific overrides.
- Analyzed repo · Target Git repository on disk being analyzed.
- Commit script · Generates commit history artifacts consumed by the Java extractor.
gittruckfactor/scripts/commit_log_script.sh - Log awk · Post-processes commit log output into analysis-ready records.
gittruckfactor/scripts/log.awk - Linguist script · Runs Linguist-based preprocessing for file classification/filtering.
gittruckfactor/scripts/linguist_script.sh - Linguist rb · Ruby helper used by the Linguist preprocessing step.
gittruckfactor/scripts/linguist.rb - Repo info · Repository-specific alias, filter, and module tuning inputs.
gittruckfactor/repo_info
Java Pipeline
Main orchestration, extraction, normalization, persistence, and metric computation.
- Main entry · Primary executable entry point for a single repository analysis.
gittruckfactor/src/aserg/gtf/GitTruckFactor.java - Rep list · Entry point for batch or list-based execution.
gittruckfactor/src/aserg/gtf/GitTruckFactorRepList.java - Task base · Coordinates analysis stages and shared execution flow.
gittruckfactor/src/aserg/gtf/task/AbstractTask.java - Git log · Consumes commit-history artifacts and turns them into structured commit data.
gittruckfactor/src/aserg/gtf/task/extractor/GitLogExtractor.java - File info · Builds file-level metadata used by ownership analysis.
gittruckfactor/src/aserg/gtf/task/extractor/FileInfoExtractor.java - Linguist · Applies language/filter metadata to file selection and classification.
gittruckfactor/src/aserg/gtf/task/extractor/LinguistExtractor.java - Alias handler · Merges developer aliases before authorship metrics are computed.
gittruckfactor/src/aserg/gtf/task/AliasHandler.java - DOA calc · Computes degree of authorship as an intermediate ownership metric.
gittruckfactor/src/aserg/gtf/task/DOACalculator.java
Domain & Storage
Authorship model and JPA-backed persistence layer.
- Persist thread · Buffers or background-writes analysis state to storage.
gittruckfactor/src/aserg/gtf/dao/PersistThread.java - DAO base · Shared data-access foundation for persisted analysis entities.
gittruckfactor/src/aserg/gtf/dao/GenericDAO.java - Authorship model · Developer, file, repository, and authorship entities used by the analysis.
gittruckfactor/src/aserg/gtf/model/authorship/Repository.java
Truck Factor
Algorithmic computation of truck factor and its result.
- TF core · Abstract truck-factor algorithm interface and execution contract.
gittruckfactor/src/aserg/gtf/truckfactor/TruckFactor.java - Greedy TF · Primary greedy truck-factor computation strategy.
gittruckfactor/src/aserg/gtf/truckfactor/GreedyTruckFactor.java - Pruned TF · Alternative greedy strategy with pruning optimizations.
gittruckfactor/src/aserg/gtf/truckfactor/PrunedGreedyTruckFactor.java - TF result · Final truck-factor output and related metadata.
gittruckfactor/src/aserg/gtf/truckfactor/TFInfo.java
Connections 24
- Analyzed repo → Commit script: scan history · The target repository is inspected to produce commit history artifacts.
- Analyzed repo → Linguist script: classify files · The target repository is scanned for file-language metadata.
- Commit script → Log awk: parse output · Commit log output is normalized into structured records.
- Linguist script → Linguist rb: run filter · Linguist preprocessing delegates to the Ruby helper.
- Repo info → File info: file filters · Filtered-file and module hints influence file metadata extraction.
- Repo info → Alias handler: alias map · Alias definitions are used to normalize developer identities.
- Main entry → Task base: start · Main entry delegates orchestration to the task pipeline.
- Rep list → Task base: start · Batch entry also delegates to the shared task pipeline.
- Task base → Git log: extract commits · Orchestrates commit-history ingestion.
- Task base → File info: extract files · Orchestrates file metadata ingestion.
- Task base → Linguist: filter files · Orchestrates optional Linguist-based file filtering.
- Task base → Alias handler: normalize ids · Applies alias merging before authorship computation.
- Task base → DOA calc: compute doa · Triggers the Degree of Authorship stage.
- Task base → Persist thread: persist state · Analysis state is written through the persistence layer.
- Git log → DAO base: store commits · Structured commit data is persisted.
- File info → DAO base: store files · File metadata is persisted.
- Linguist → Authorship model: enrich files · Language and classification data feed the domain model.
- Alias handler → Authorship model: merge authors · Normalized developer identities are applied to authorship entities.
- DOA calc → Authorship model: update ownership · Degree-of-authorship values are stored in authorship entities.
- Authorship model → TF core: ownership input · Persisted authorship and repository data feed truck-factor computation.
- TF core → Greedy TF: strategy · Greedy implementation provides the main computation path.
- TF core → Pruned TF: strategy · Pruned implementation provides an alternate computation path.
- Greedy TF → TF result: produce result · Greedy computation emits the final truck-factor result.
- Pruned TF → TF result: produce result · Pruned computation emits the final truck-factor result.