Cross project API control can play a vital role in managing a well-organized codebase. In this post, we’ll take a look at how to achieve API control between projects using the Modules feature in Structure101 Studio.
For a full walkthrough of the examples mentioned below in action, take a look at the embedded video (8 mins).
Controlling Access to a Folder by Other Projects
To begin, you’ll need to switch on the modules feature in the Project properties dialog by going to the Modules tab, and enabling whichever of the three kinds of modules checking you want to apply to your project:
We’ll also change some of Structure101 Studios default UI settings by de-emphasising (deselecting) cyclic dependency tangle checking, and emphasizing (selecting) the module violations instead:
We’ll also extend the “Module violations” panel to hide the “Structural over-complexity” panel:
The first kind of module API checking is where we have some code in a folder (possibly a separate project), and wish to control how that folder is accessed by other parts of this project.
For example, we want to limit the access to the code inside ‘crypto’ to this ‘headers’ folder, so nothing other than what we put in the ‘headers’ folder should be used from outside of ‘crypto’:
The way we achieve that is to use the ‘Convert to a module’ command on the ‘crypto’ folder. What that effectively does is say that the ‘crypto’ folder is now considered to be a protected scope:
We will see that a lot of violations have appeared within the ‘Module violations’ panel, and that’s because nothing within ‘crypto’ so far has been defined to be public. We can do that using the module’s ‘Make public to enclosing module’ command, which now says that the ‘headers’ folder can be used externally. This in turn means that most of those violations disappeared as those dependencies are now allowed:
In this case there is still a dependency showing between ‘core’ – which is outside of the public area – and ‘crypto-algos’ which is inside the ‘crypto’ module:
So using the Violating item list in the Module violation panel, we can navigate (by clicking) quickly to the source of the dependency, and drill down (double-clicking) into ‘crypto-algos’ to where those dependencies go, and get a better feel for what the problem is:
Here, the problem is that there’s a function (TestVector) referencing a member in a class contained within the ‘crypto’ module, and a supporting file-to-file includes dependency as well.
We may decide to move ‘hkdf_sha256_32.h’ into the public area and create an action for that. By moving it (drag-and-drop) to ‘headers’, we are now violation free. All that’s being used here at this point is ‘headers’ as intended, in the public folder:
The next thing we’re going to look at is deprecation. We have a common situation where we have an object that is currently in a public header but we want to remove, and deprecate it. Let’s say for this example that we want to deprecate ‘CountBits’. Perhaps it should never have been used, maybe we’re moving it to some other part of the project, or it’s going to form part of an internal API, or something else. We can do that quite simply by selecting ‘CountBits’, going to the Module submenu, and selecting Deprecate:
We can see that a red triangle has appeared on ‘CountBits’, indicating that that’s deprecated and shouldn’t be used:
We can see that the deprecation violation is shown in the ‘Dependency breakout’ panel when the dependency on ‘CountBits’ is selected (click):
At some point in the future we might expect to delete CountBits from its current location, or perhaps move it to a non-public location.
Inter-project Dependency Control
The third and final kind of dependency control between folders/modules/teams, is to control which projects can use which other projects, or which folders can use which other folders. In order for that to happen, both folders must be converted into modules. For this example, we’ll convert ‘controllers’ and ‘addr’ to modules as before:
Now we can see in the Module violations window that this has created a lot of violations. If we select (click) one of these dependencies, the Dependency breakout panel shows that this is called a ‘Requires violation’ which, in this case means that we haven’t allowed dependencies to occur between ‘controllers’ and ‘crypto’ yet:
We can do this very simply by selecting the violation in the Structure view, and in the Module submenu, selecting ‘Allow’, and if we select that dependency again, we can see it creates a direct dependency between the folders:
Normally a folder wouldn’t depend directly on another folder. There may be a dependency between code that both folders contain, but here it adds a direct dependency, indicating that dependency at that interface is allowed.
Some of the violations we may choose to leave in place, so downstream the developers can see that there’s a problem there, and do something about it.
If we go to the ‘Summary’ view in Studio, we’ll see that the module information is included in the Key Measures and Modules sections:
Repairing Problems with Structure101 Workspace
Developers using Structure101 Workspace can access the same module information by opening the saved Studio project, and can go directly to any module related violations under the Modules section in the PROBLEM ITEMS window:
They can then navigate directly to any problems on that list, and from those problems, (when the IDE Connector plugin is in use) jump directly across to the source code where it can be repaired.
Problem Tracking with Structure101 Dashboard
This module information is also included in Structure101 Dashboard, you can track how it’s changing over time, the total number of module violations on the chart, as well as being able to see the list of specific violations, along with the other structural measures:
For a full walkthrough of the examples mentioned here in action, take a look at the embedded video (8 mins).
For a full Structure101 Studio feature walkthrough, watch this video playlist.
Subscribe to our YouTube channel to catch future videos like this.