{"id":20877517,"url":"https://github.com/fburato/highwheel-modules","last_synced_at":"2025-05-12T16:30:38.594Z","repository":{"id":31656545,"uuid":"128535513","full_name":"fburato/highwheel-modules","owner":"fburato","description":"Bytecode based architecture verification","archived":false,"fork":false,"pushed_at":"2023-11-04T20:33:47.000Z","size":694,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-01T07:53:30.567Z","etag":null,"topics":["analysis","architecture","bytecode","dependency-graph","java","specification"],"latest_commit_sha":null,"homepage":"","language":"Scala","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/fburato.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-04-07T14:21:28.000Z","updated_at":"2022-01-06T12:44:17.000Z","dependencies_parsed_at":"2022-09-26T21:40:56.092Z","dependency_job_id":"cb659ff7-2d5c-489d-8d75-73796327a3a2","html_url":"https://github.com/fburato/highwheel-modules","commit_stats":null,"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fburato%2Fhighwheel-modules","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fburato%2Fhighwheel-modules/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fburato%2Fhighwheel-modules/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fburato%2Fhighwheel-modules/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fburato","download_url":"https://codeload.github.com/fburato/highwheel-modules/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253776665,"owners_count":21962525,"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":["analysis","architecture","bytecode","dependency-graph","java","specification"],"created_at":"2024-11-18T06:57:15.400Z","updated_at":"2025-05-12T16:30:38.253Z","avatar_url":"https://github.com/fburato.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://github.com/fburato/highwheel-modules/actions/workflows/scala.yml/badge.svg)](https://github.com/fburato/highwheel-modules/actions/workflows/scala.yml)\n# Highwheel-Modules\n\nHighwheel modules is an extension of the class dependency visualisation tool [Highwheel](https://github.com/hcoles/highwheel)\nby Henry Coles to express, measure and verify the structure and the design of Java projects.\n\nIn general it is reasonable to expect that Java project are organised in logical entities (or modules) that serve a \nspecific concern: a module is used to contain the core business logic of the application, a module is used to \naccomodate the outer interface through a web api, a module is used to contain the clients to connect to persistent \nstorage devices and external services etc. Highwheel modules offers:\n\n* A language to describe and define software modules and the relation between them (module specification).\n* An analysis scanner that takes the classes of a project and fits them in the defined modules.\n* A dependency calculator that determines if the provided module specification is observed by the project or not.\n* Command line tool and a maven plugin to apply validate the specification.\n* Measurement of architectural metrics (fan-in and fan-out) useful to verify stability and abstractness of the modules.\n\n## Specification language\n\nHighwheel-module specification language can be described by the following grammar in EBNF form:\n\n```\nModules ::= [\"prefix:\" RegexLiteral \"\\n\"]\n            [\"whitelist:\" RegexLiteral{, RegexLiteral} \"\\n\"]\n            [\"blacklist:\" RegexLiteral{, RegexLiteral} \"\\n\"]\n            [\"mode:\" Mode]\n            \"modules:\" \"\\n\"\n              { ModuleDefinition }\n            \"rules:\" \"\\n\"\n              { RuleDefinition } \n\nModuleDefinition ::= ModuleIdentifier = RegexLiteral{ , RegexLiteral } \"\\n\"\n\nModuleIdentifier ::= \u003cjava identifier\u003e\n\nRegexLiteral ::= \"\u003cglob regex\u003e\"\n\nMode ::= \"STRICT\" | \"LOOSE\"\n\nRuleDefinition ::= DependencyRule | NoDependencyRule | OneToManyRule | ManyToOneRule\n\nDependencyRule ::= \u003cjava identifier\u003e \"-\u003e\" \u003cjava identifier\u003e { \"-\u003e\" \u003cjava identifier\u003e } \"\\n\"\n\nNoDependencyRule ::= \u003cjava identifier\u003e \"-/-\u003e\" \u003cjava identifier\u003e\n\nOneToManyRule ::= \u003cjava identifier\u003e \"-\u003e\" \"(\" \u003cjava identifier\u003e {\",\" \u003cjava identifier\u003e} \")\"\n\nManyToOneRule ::= \"(\" \u003cjava identifier\u003e {\",\" \u003cjava identifier\u003e} \")\" \"-\u003e\" \u003cjava identifier\u003e\n```\n\nIn order for a specification to be compiled correctly:\n\n* At least one module needs to be defined.\n* All the identifiers used in the rules section need to be defined in the modules section.\n* The file needs to end with a new-line\n\nAn example of specification can be found in this project in the `spec.hwm` files of every project modules and would look\nlike this:\n\n```\nprefix: \"com.github.fburato.highwheelmodules.\"\n\nmodules:\n    Utils = \"utils.*\"\n    Core = \"core.*\"\n    Cli = \"cli.*\"\n    MavenPlugin = \"maven.*\"\n    Parser = \"bytecodeparser.*\"\n    Model = \"model.*\"\nrules:\n    (MavenPlugin, Cli) -\u003e Core\n    Core -\u003e Parser\n    (Core, MavenPlugin, Cli, Parser, Model) -\u003e Utils\n    (Core, Parser) -\u003e Model\n```\n\nAn equivalent way of providing the specification is to use the `prefix` preamble, which allows to automatically\nadd to all module specification a prefix to compact the definition.\n\nWith the usage of prefix, the following definition:\n\n```\nmodules:\n    Algorithms = \"com.github.fburato.highwheelmodules.core.algorithms.*\"\n    ExternalAdapters = \"com.github.fburato.highwheelmodules.core.externaladapters.*\"\n    Specification = \"com.github.fburato.highwheelmodules.core.specification.*\"\n    ModuleAnalyser = \"com.github.fburato.highwheelmodules.core.analysis.*\"\n    Facade = \"com.github.fburato.highwheelmodules.core.AnalyserFacade\"\n\nrules:\n    Facade -\u003e (ModuleAnalyser, Specification, ExternalAdapters)\n    ModuleAnalyser -\u003e Algorithms\n    Facade -/-\u003e Algorithms\n```\n\nis equivalent to\n\n```\nprefix: \"com.github.fburato.highwheelmodules.core.\"\n\nmodules:\n    Algorithms = \"algorithms.*\"\n    ExternalAdapters = \"externaladapters.*\"\n    Specification = \"specification.*\"\n    ModuleAnalyser = \"analysis.*\"\n    Facade = \"AnalyserFacade\"\n\nrules:\n    Facade -\u003e (ModuleAnalyser, Specification, ExternalAdapters)\n    ModuleAnalyser -\u003e Algorithms\n    Facade -/-\u003e Algorithms\n```\n\nWhitelisting and blacklisting of modules is also supported (as of `1.5.0`). By specifying whitelist and blacklists\nin the specification, you can force Highwheel modules to focus only on certain classes or exclude certain classes from \nanalysis respectively. \n\nBy whitelisting you are forcing the bytecode analyser to consider elements identified to be added to the dependency \ngraph building algorithm only if they match any of the regexes in the whitelist.\n\nBy blacklisting, you are forcing the bytecode analyser to ignore elements identified to be added to the dependency\ngraph building algorithm if they match any of the regexes in the blacklist.\n## Modes of operation\n\nHighwheel modules supports two modes of operation: **strict** and **loose**.\n\nWhen running on strict mode, the rules are interpreted as follows:\n\n* `A -\u003e B` requires that there must exist a direct dependency between a class in module `A` and a class \nin module `B`. The rule is violated if there is no such dependency or if `A` depends on `B` indirectly through other\nmodules\n* `A -/-\u003e B` requires that if `B` is reachable from `A` then there is no explicit dependency between classes\nof `A` and classes of `B`. The rule is violated if there is such a direct dependency.\n\nMoreover, a strict analysis fails if there are dependencies in the actual dependency graph calculated from the bytecode\nthat do not appear in the specification. Basically a strict analysis requires the entire dependency graph to be\nexplicitly written in the specification in order for it to pass.\n\nIt is an analysis mode suggested to identify circular dependencies (i.e. if there is no such rule as `A -\u003e A` in the\nspecification but the circular dependency on `A` exists, the analysis will fill) and to enforce strong design decisions.\n\nWhen running on loose mode, the rules are interpreted as follows:\n                           \n* `A -\u003e B` requires that `B` is reachable from `A` in any way. The rule is violated if `B` is not reachable from `A`\n* `A -/-\u003e B` requires that `B` is not reachable from `A` in any way. The rule is violated if `A` depends on `B`\n\nBasically, the loose analysis is a whitelisting and blacklisting analysis: certain dependency are allowed to exist\nand certain are not.\n\nIt is an analysis mode suggested to ensure very specific properties in the dependency graph and not the entire\nstructure of it.\n\nIn order to use the loose analysis mode, specify the mode in the specification file as follows.\n\n\n```\nprefix: \"com.github.fburato.highwheelmodules.core.\"\nmode: LOOSE\n\nmodules:\n    Algorithms = \"algorithms.*\"\n    ExternalAdapters = \"externaladapters.*\"\n    Specification = \"specification.*\"\n    ModuleAnalyser = \"analysis.*\"\n    Facade = \"AnalyserFacade\"\n\nrules:\n    Facade -\u003e (ModuleAnalyser, Specification, ExternalAdapters)\n    ModuleAnalyser -\u003e Algorithms\n    Facade -/-\u003e Algorithms\n```\n\nThe default mode is `STRICT`, but the mode can be explicitly indicated with `mode: STRICT` in the same position.\n\n## Usage \n\nHighwheel modules can be used by including in your build the appropriate plugin, depending on your build tool of choice:\n\n- Maven: include in your build the [highwheel-modules-maven-plugin](https://github.com/fburato/highwheel-modules-maven-plugin).\n- SBT: include in your build the [sbt-highwheel](https://github.com/fburato/sbt-highwheel) plugin.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffburato%2Fhighwheel-modules","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffburato%2Fhighwheel-modules","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffburato%2Fhighwheel-modules/lists"}