Skip to content

Latest commit

 

History

144 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Moose-CI

Moose-CI runs automatic Moose analyses on software projects.

Disclaimer: This project is at a very early stage. It only has a few features and may contain bugs.

You can request features in the issues tab.

Table of Contents

Features

Some of features it should offer:

  • run alone ("headless" mode)
  • load a project (either from command line or in a configuration file)
  • accept projects inany programming language that Moose can handle (C, Java, Pharo, Python, Typescript,...)
  • run a list of analyses (either "standard" ones, or some specified in a configuration file)
  • output the results as JSON and console text
  • output the results in other formats (XML, CSV, HTML,...)

Some metrics and analyses that are envisionned:

  • size (LOC, # of classes,...)
  • report number of entities that fail the rules
  • list too big classes (based on LOC or # members)
  • list too big methods/functions (based on LOC)
  • list of too complex methods/functions (based on cyclomatic complexity)
  • list of too large method/function APIs (# number of parameters)
  • packages/modules in cyclic dependencies
  • list of code clones

In would be good to be able to output some visualizations already available in Moose:

  • DSM (Dependency Structure Matrix)
  • Architectural view
  • System complexity
  • Distribution map
demo

For users

Usage with Docker

The easiest way to run Moose-CI is with Docker. You do not need Pharo or any other dependency.

First, pull the image:

docker pull ghcr.io/moosetechnology/moose-ci:latest

From the project directory, initialize it as a Moose-CI project. This creates a moose-ci.ston config file that you can customize:

docker run -v "$(pwd):/src" ghcr.io/moosetechnology/moose-ci:latest init

Then run the analysis with the analyze command:

docker run -v "$(pwd):/src" ghcr.io/moosetechnology/moose-ci:latest analyze

You can also run Moose-CI on a project without initializing a config file by passing the project path:

docker run -v /path/to/your/project:/src ghcr.io/moosetechnology/moose-ci:latest analyze /src

The project is mounted in the container at /src, so you need to pass that path to the analyze command.

Available commands

  • init: create a new moose-ci config file.
  • analyze: analyze the current directory using the existing config file.
  • analyze <project-path>: analyze the project.

Report output

Running analyze prints the report to the console and writes it to files in the output directory (.moose-ci/report/ by default, relative to the analyzed project).

By default a JSON report is written to report-<TIMESTAMP>.json:

{
  "metrics" : {
    "files" : 8,
    "loc" : 5,
    "packages" : 2,
    "classes" : 3
  },
  "violations" : [
    {
      "rule" : "No docstring",
      "severity" : "Hint",
      "count" : 3,
      "entities" : [
        {
          "entity" : "DummyClass",
          "file" : "relative/path/to/no_docstring.py",
          "startLine" : 1,
          "endLine" : 2
        }
      ]
    }
  ]
}

Violations are grouped by rule. Each group contains the rule name, its severity, the number of violating entities and the details of each entity (name, file and source lines).

You can configure the output in moose-ci.ston:

#outputFormats : [
		#json
],
#outputPath : '.moose-ci/report'
  • #outputFormats: list of formats to write. #json is the only format available for now.
  • #outputPath: directory (relative to the project) where the report files are written.

Configuration

Moose-CI uses a moose-ci.ston config file. Run moose-ci init to create one.

You can configure the report output formats and location here too (see Report output).

You can update the rules list and customize each rule's threshold:

...
#rules : [
		#long_file: 1000,
		#no_docstring,
		#too_many_parameters: 10
]
...

You can also choose which metrics to compute:

...
#metrics : [
		#files,
		#loc,
		#packages,
		#classes
]
...

Metrics can be omitted (or set to an empty list) if you do not want to compute any metric.

Available rules

Key Threshold Description
#long_file 1000 Reports files whose number of lines of code exceeds the threshold.
#no_docstring N/A Reports functions, methods and classes that are missing a docstring.
#too_many_parameters 10 Reports methods whose number of parameters exceeds the threshold.
#large_class 20 Reports classes that have too many methods or attributes.
#local_var_naming N/A Reports local variables and parameters whose names do not respect the naming convention.
#unused_local_variable N/A Reports local variables that are written but never read.
#unused_parameter N/A Reports function and method parameters that are never used.
#unused_private_method N/A Reports class-private methods that are never invoked.
#shadowed_attribute N/A Reports attributes whose name duplicates their containing class name.
#function_naming N/A Reports functions whose names do not comply with the naming convention.

Available metrics

Key Description Applicable languages
#files Number of source files. all
#loc Total lines of code. all
#packages Number of packages. all
#classes Number of classes. all

Usage with GitHub Actions

You can run MooseCI in CI with the Setup MooseCI GitHub Action. Add the action to a workflow:

name: MooseCI
on: [push, pull_request]
permissions:
  contents: read
  actions: write
  pull-requests: write
jobs:
  analyze:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: moosetechnology/setup-MooseCI@main
        with:
          project-path: .
  • project-path: the folder to analyze, relative to the workspace. Default: .
  • actions: write is needed to upload the report artifact.
  • pull-requests: write is needed to comment the report link on pull requests.
  • The moose-ci.ston config file must be placed inside the analyzed project folder (see Configuration).
  • On pull requests, the action comments the report download URL and the analysis summary on the PR.

For developers

Installation

Load MooseCI in a Moose image with Metacello:

Metacello new
  baseline: 'MooseCI';
  repository: 'github://moosetechnology/MooseCI:master/src';
  load.

Create a new rule

A rule is a subclass of MCIAbstractQualityRule. It must implement:

  • class >> key: a unique identifier, e.g. #too_many_lines
  • class >> defaultThreshold: the threshold used when none is set in the config
  • contextFilterBlock: a block that selects the entities to analyze
  • queryHandler: a block that decides what counts as a violation

Example of a simple rule that reports files with too many lines of code:

MCIAbstractQualityRule <<  #MCITooManyLinesRule
	slots: {};
	package: 'MooseCI-QualityRules'

MCITooManyLinesRule class >> key [
	^ #too_many_lines
]

MCITooManyLinesRule class >> defaultThreshold [
	^ 500
]

MCITooManyLinesRule >> contextFilterBlock [
	^ [ :collection | collection select: [ :each | each isModule ] ]
]

MCITooManyLinesRule >> queryHandler [
	^ FamixCBQueryHandler on: (FQSelectScriptQuery script: [ :entity |
		entity numberOfLinesOfCode > self threshold ])
]

You can also override ruleName, defaultSeverity, applicableLanguages and description. applicableLanguages is #all by default. You can specify it by passing a list of languages, e.g. #( #python ). Rules that do not use a threshold return -1 as their defaultThreshold (e.g. #no_docstring).

New rules are discovered automatically from their key, so no registration is needed. To use a rule, add its key to the #rules list in moose-ci.ston:

#rules : [
	#too_many_lines: 300,
	#no_docstring
]
  • #too_many_lines: 300: enables the rule with a custom threshold.
  • #no_docstring: enables a rule that has no threshold.

To make a rule part of the default config created by moose-ci init, add its key to MCIQualityRules class >> pythonRules (or javaRules / defaultRules).

Create a new metric

A metric is a subclass of MCIAbstractMetric. It must implement:

  • class >> key: a unique identifier, e.g. #methods
  • compute:: a method that computes the value from a Moose model

Example of a simple metric that counts the number of methods:

MCIAbstractMetric << #MCINumberOfMethodsMetric
	slots: {};
	package: 'MooseCI-Metrics'

MCINumberOfMethodsMetric class >> key [
	^ #methods
]

MCINumberOfMethodsMetric >> compute: aModel [
	^ aModel allMethods size
]

You can also override metricName, description and applicableLanguages. metricName defaults to the key as a string. applicableLanguages is #all by default. You can specify it by passing a list of languages, e.g. #( #python ).

New metrics are discovered automatically from their key, so no registration is needed. To use a metric, add its key to the #metrics list in moose-ci.ston:

#metrics : [
	#methods,
	#loc
]

Metrics can be empty (#metrics : [ ]) or omitted entirely when you do not want to compute any metric.

To make a metric part of the default config created by moose-ci init, add its key to MCIMetrics class >> pythonMetrics (or javaMetrics / defaultMetrics).

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages