What is a .mttm_config?

What is a .mttm_config?

A .mttm_config is a file that you put at the root of the directory. It will tell us what we need to analyse and how we need to analyse it. But Let’s have a precise look at what it does.

General structure

The .mttm_config file needs to be exactly name this way and, as said, it needs to be a the root of your directory. We will auto-detect it. It follows a json structure (if this structure is not conform, we will emeit a warning in our log system - currently you will not see it.)

A short example

{
    "configPath": {
       "path": "myProject.xcodeproj"
    },
    "imports": [
    {
       "name": "RxSwift",
       "path": "Carthage/Checkouts/RxSwift/RxSwift"
    }
    ],
    "rules": [
     {
       "name": "ViewController",
       "pattern": "ViewController?$",
       "use": [
         "ViewModel"
       ]
     },
     {
       "name": "ViewModel",
       "pattern": "ViewModel?$",
     }
    ]
}

This is a simple example where you tell us the path of the project to be analysed, some imports that you want to include in your analyse and the beginning of an architecture where ViewController can talk with ViewModel.

## configPath entry

"configPath": {
  "path": "myProject.xcodeproj"
}

This entry indicates the path to the project that needs to be analysed. It is optional because, by default, we will detect in that order:

  • a package.swift file (and thus treat your directory as a SPM directory)
  • the first xcworkspace that we can find (and we will base our analyse on it’s structure - if it is a playground then our analyse will currently fail)
  • the first XCodeProj that we can find

If can not find any of those, then we will analyse all the swift files that we will find. If you use this entry in your json, be sure the path is correct (relative to your directory), or our analyse will fail.

imports entry

"imports": [
]

This entry is optional. If used, every element of it will be included in the analyse. For example, you want to include a deep analyse of a package like RxSwift, just add this entry to it:

{
    "name": "RxSwift",
    "path": "Carthage/Checkouts/RxSwift/RxSwift"
}

Rules entry

"rules": [
]

This entry is used to define your architectural patterns (and it will be used to display them in the graph and to analyse your code). The actual breach detection is based on naming convention. If the declaration of your class/directory does not follow those conventions, then we could potentially detect failures that will be false positives.

An entry is formatted like this:

{
      "name": "ViewController",
      "pattern": "ViewController?$",
      "use": [
        "ViewModel",
        "ViewControllerDelegate",
        "Helpers"
      ],
      "forbidden": [
        "Model"
      ]
}
  • name will be used to recognise the rule in the rest of the json and also as the name of your element in the “your patterns view” (so be smart and use descriptive words).
  • pattern is the regulaer expression gthat will be applied to the naming convention (in our example: a ViewController must be named with the suffix ViewController or it will not be detected as a ViewController). It works with any kind of regular expression. The naming convention works also for folders or directories.
  • use defines all the other element that the actual element can use. In our example, ViewController can use ViewModel, ViewControllerDelegate and Helpers.
  • forbidden is here to reinforce the fact that ViewController should never talk to Model.

##How does the detection work?

Let’s say that you have this structure in your projects:

|
|--> ViewController
     |---> HomeViewController
|--> ViewModel
     |---> HomeViewModel
|--> Model
     |---> Element

Inside HomeViewController, we have detected this line:

let myVar = HomeViewModel.generateName()

This will generate a path in our description like this: HomeViewController > ViewControllers > ViewModels > HomeViewModel.

Considering the rule established before, this is a valid path because we found HomeViewModel that respects the rules you have defined.

Now let’s say we see this line:

let myVar = HomeViewModel.element.name

This will generate a path in our description like this: HomeViewController > ViewControllers > ViewModels > HomeViewModel > Model > Element

Considering the rule established before, this is an unvalid path because we found HomeViewModel that respects the rules you have defined but Model is forbidden so we will define this path as forbidden even if it is going through the ViewModel.

Safe path

Say you have part of your app that is considered as safe and that should not be analysed, you can add this to your rules:

{
      "name": "RxSwift",
      "pattern": "RxSwift?$",
      "isSafePath": true
}

Everything under that structure will be considered as safe and will not generate any failure in your architecture.

Are we missing rules?

Yes, we know that this is not perfect, so give us some feedback, be rude, do not hesitate to shoot emails, tweet. Our intention is to make you happy so whatever remark, change, improvment is more than welcome (it is requested.)

A complete example

{
  "configPath": {
      "path": "myProject.xcodeproj"
  },
  "imports": [
  {
      "name": "RxSwift",
      "path": "Carthage/Checkouts/RxSwift/RxSwift"
  }
  ],
  "rules": [
    {
      "name": "ViewController",
      "pattern": "ViewController?$",
      "use": [
        "ViewModel",
        "ViewControllerDelegate",
        "Helpers"
      ],
      "forbidden": [
        "Model"
      ]
    },
    {
      "name": "ViewModel",
      "pattern": "ViewModel?$",
      "use": [
        "Model"
      ]
    },
    {
      "name": "Model",
      "pattern": "Model?$"
    },
    {
      "name": "Coordinator",
      "pattern": "Coordinator?$",
      "use": [
        "ViewControllerDelegate"
      ]
    },
    {
      "name": "ViewControllerDelegate",
      "pattern": "ViewControllerDelegate?$"
    },
    {
      "name": "Helpers",
      "pattern": "Helpers?$",
    },
    {
      "name": "RxSwift",
      "pattern": "RxSwift?$",
      "isSafePath": true
    }
  ]
}