Last Directions US and EMEA, I had the opportunity to talk about – uhm – myself. Well, not really – about my tools. It was a weird experience – but it got more attention than I ever expected.
Now, during that session, I showed a tool that I wanted to put out there for sooooo long: a way to analyze your C/AL Source Code with PowerShell.
This was actually an “let’s see what we can do and how far we can go”-challenge during our free time ;-), where the .Net part (which is the majority of the work) wasn’t done by me, although I was quite (let’s say “overly”) involved with the entire evolution of it ;-). The tool might not be completely new to you. I have been using it for quite some time to talk about some things within the product, like:
- The Event Publishers in different versions
- Triggers & Procedures
So as you can see – it’s basically about analyzing C/AL code.
Also at NAVTechDays, I spent a topic on it during my session with Vjeko. You can see it here:
When we talk about the tool, we call it the “ModelToolsAPI“. It’s a PowerShell-module-dll that my partner in crime wrote, “on top of” the existing “Microsoft.Dynamics.Nav.Model.Tools.dll”, which is a library that serves the PowerShell Merge-CmdLets provided by Microsoft. It basically builds you an Object Model from your text files, which it needs to be able to merge in a smart way. For example, the tool knows all objects, or properties, what fields, relationships, … and a hell-of-a-lot more. And simply said: when you have an object model, you can work with it. When you only have a text-file, all you can do is search in text.
And I was wondering – what if we could do this in PowerShell? Because simply, I don’t know what I want to analyze today, and how I want the output to look like. Or better yet – what if I want to make the analysis part of my build, or commit, or pull request, or .. you know what I mean: part of my integration scenario! For analyzing code, PowerShell all of a sudden made all the sense in the world! At least for us ;-).
But we saw two problems with the out-of-the-box “Microsoft.Dynamics.Nav.Model.Tools”:
It sees code as just text – so it doesn’t really “understand” code. And with understand, I mean:
- being able to trace fields, variables, procedures, keys, .. back to where they are used in code
- Understand an “if” statement and any other statement for that matter
- Being able to track complexity of a certain procedure
- Its default object structure was quite complex.
So, my fellow nerd started to crunch a better, more understandable object model out of it, and started to write a code tokenizer (if I can call it like that) for C/AL code, basically mapping all words in code to something it understands.
As a result, we have a complete object model, understanding code, which we can query any way we like. Even more, because we’re using the default “Microsoft.Dynamics.Nav.Model.Tools”, we also have its modification- and export-functionality at our disposal (you hear me coming? ControlIDs? .. (but that’s for a later blogpost) :-)). And still even more, because (again) we are using default Microsoft libraries, with an update, we simply tap into the new version, and off we go :-).
Where can I find it?
I understand it’s not going to be easy to get started with a tool like this. But if you pick up the challenge, you won’t regret it! I tried to make it as approachable as at all possible:
You can just clone/fork/download from my github repository here: https://github.com/waldo1001/Waldo.Model.Tools
- The repo contains readme-files and scripts to get you started. Just export a txt-file from your database, and you’re good to go. Almost.
Before you can use the tool, you need to get a license. Don’t worry, it’s free and only takes a few minutes. I even put it in a script and explained it in the readme. Don’t worry, we have no intention to ever monetize this tool.
- Just fill in your details in the browser when it pops up, and you’ll get a license mailed to you, which you need to put in the same folder as the dlls.
- Now, you’re good to go load your object model into a variable by calling the “Get-NAVObjectModel” (which points to a text-file), and you are about to analyze it.
To get you started on anything useful, I have foreseen some scripts here, like:
- Some basic examples
- Great example on why the code-analysis was necessary!
- Count the number of commits – and analyze the commits
Once you get used to it, it’s super-readable!
Now it’s up to you!
There are quite a number of scenarios where we apply this tool.
Just now, we are about to rewrite our product in AL. With this tool, we did a complete, in depth dependency analysis for figuring what apps we would end up with. It gave us an overview of problems with “circular dependencies”, and an easy way to document all changes we did for certain modules/apps. I’m definitely coming back to that exercise!
We also used this for figuring out and fixing controlid-errors – if you ever encountered them, you sure know what I’m talking about! ;-).
And much much more – basically, it’s a bit up to you to get familiar with it (if you at least want it to be), and apply it on whatever you want to apply it.
Expect more scripts and blogs about this in the future, but please do know you can contribute as well (just fork and make a pullrequest), … .
Wow, this sounds like a really great tool! I think I could need it myself. Good yob and thumbs up!
I’m looking forward to see what you will do with it 😉
Nice tool Waldo. Already ran some checks on this through our code base. Question, isn’t true that the Cyclomatic Complexity is at least 1? Currently with only 1 path it calculates to 0.
Another question, would be helpful to also include the Halstead volume. Together with the cyclomatic complexity, number of lines of code, it’s possible to calculate the maintainability index, like we have this in Visual Studio projects.
All nice suggestions :-). You’re welcome to put them on GitHub!
It seems to be a great tool but I’m having some issues with it.
I’ve tried to load objects from a BC W1 database and from a NAV 2017 database. The objects are loaded with some warnings that I believe to be normal but when I try the $Model.NAVObjects.Count command it returns me 0.
Thanks for your time!
Did you request a license?
Yes, I’ve requested the license and when I run the RequestLicense script everything seems to be ok.
Great Tool, is it work for AL project files.
Nope, it only works for C/AL.
We need something completely different for AL – at some point, Microsoft will document their code analysis framework (as I was told…).
We tried to use the powershell to build the model but we are getting license “EXPIRED” error. We tried requesting new licenses and still the error continues.
Exact Error Message: Get-NAVObjectModel : EXPIRED
Your help is appreciated.
I recently refreshed the dlls in my repo. Did you download the latest version?
Yes, we did cloned it from your repo early this week.
Did you update very recently though?
Last week. Sorry, but I can’t do anything about it now :-/. I’ll test it when I have time..
Sorry to bother you again on this.
By any chance did you have a look at this issue? You help is much appreciated at this point.
This should have been fixed quite a while ago – did you try again?
Which versions of NAV objects this tool will be able to analyze?
It should work for anything C/AL since NAV2013….
Thank you. So it won’t work for the versions older than NAV 2013. (i.e. NAV 5.0)
Probably not. It’s highly dependent from the “microsoft.dynamics.nav.model.tools.dll”, and that only exists from NAV2013 (along with the powershell tools to merge). I don’t think it “understands” forms, for example..
That’s true. When you run application merge commands with forms and dataports in the text file comparison – they error out. As these are based off of microsoft.dynamics.nav.model.tools.dll. Thank you Waldo.