Last time we posted about lints and static analysis and introduced the
netglade_analysis package that we use in our projects. Since then, we have even further improved our settings and we’d like to share it with you today.
To recap, we believe that static analysis helps write better, more boring code. It points out otherwise overlooked issues, suggests better and safer methods, removes redundant code, and unifies it across teams and projects. You’ll likely end up with a very strict code, but that’s a good thing. We need the best, clearest code we can get; no questions asked.
Since last time, we added some Dart lints to our package. That alone is a huge benefit, as now we can have Dart 3 specific lints. But the biggest improvement we did was switching to DCM for Teams, a continuation of the Dart Code Metrics plugin.
DCM Teams (or Individuals for solo developers) is a newer version of DCM. The former version worked only as a Dart Analyzer plugin, while the new For Teams version works as a standalone tool. Removing the plugin’s API dramatically increased the performance. And we feel that; analysis and fixing are now blazingly fast.
Worry not, it also comes with a VSCode extension and IntelliJ plugin, so the experience in an IDE is still familiar. Hinting in editors is extremely quick (maybe even too quick), so you get hints right away when you need them. These extensions also support auto-fixing problems, all problem occurrences, and auto-fixable problems across the file, which is massively useful.
There is also a DCM Discord server where you can ask questions, report issues, or suggest improvements. We posted many issues we found during upgrades on our bigger projects, and they were fixed in the next release. When we tried to suggest some improvements or request a new configuration for a rule, our calls were promptly answered. We commend such an active approach to developing a tool as useful as this.
Another difference is the new licensing model. While the old DCM was available for free, the new one requires a paid license. Thus, maintainers can focus more on improving this amazing tool, so we are glad we can support it this way. And if you’re on the fence, you can always request a trial and try it out.
But DCM is not only a linting-and-fixing tool. While Rules might be the first thing that catches your eye, DCM can do much more. It has Assists to help you while refactoring, Metrics that analyze code maintainability, and Commands that further help you maintain your project.
We love Rules so much! It’s easily our favorite current DCM feature.
We cannot think of the best rule there is (all of them are awesome), but some of the latest rules like avoid-generics-shadowing, avoid-uncaught-future-errors, avoid-unnecessary-futures, avoid-unnecessary-overrides-in-state, or prefer-dedicated-media-query-methods can make your life a bit better.
We recommend testing the rules an a larger scale project. We did just that, and now we use these DCM settings with explanations for those we disabled.
DMC also contains Assists, which are basically extensions for your editor that can help you while refactoring. There are only two assists for now, but we believe they can be added if you have an idea for something useful. Assist “wrap with …” helps you predefine any Widget to be wrapped around a selected one, including settings like properties (child, children), if it’s a list, or on which targets it should work. And assist “Extract class to a new file” is something we have missed a lot in both VSCode and IntelliJ, as it helps you extract a class to its own file, with everything working immediately. We often first develop into one file, and then split the implementation into smaller parts, which is very useful.
While Rules help you with code and its syntax, Metrics measure its complexity. There are metrics for functions and classes, but also for files. And they are all configurable. An example would be metric “lines of code,” which measures the number of lines of a function. If your team feels like limiting lines for a function to 50 is the best thing to do, now it’s possible.
We still have to review metrics and consider which ones make sense for our case, so we cannot give you our applied knowledge. As always, give it a try.
For stuff that suits better to “run it on demand” style, there are Commands. There are the obvious ones like
format, but also commands like
calculate-metrics to measure the complexity of your code using Metrics. There are
check-exports-completeness to check that all public API types are exported and
check-unnecessary-nullable to check unnecessary nullable parameters. Then there are commands to check unused stuff
check-unused-code. And last but not least,
check-dependencies for checking if you actually use your dependencies.
We asked the founder himself, Dmitry Zhifarsky, to shed some light on the present and future of DCM:
Interview with Dmitry Zhifarsky 🧑💻
Honza: First of all, thank you for doing a great job with DCM! I use DCM every day and love it. Could you tell us why you started developing a tool for additional lints for Dart? Weren’t Dart lints enough?
Dmitry: The tool was created about 3.5 years ago in Wrike by another developer with the initial idea of calculating metrics (which is why it has ''metrics'' in its name). Then, they discovered the analyzer plugin's API and created the first few rules. Soon after, I joined the project and helped fix bugs (mostly stabilize the way we used the API) and introduce the first complex rules like
member-ordering. As for the standard Dart lints, we first had, and still have two main differences: configurability and release schedule. Not every team can and should write code the same way as others, and configurability helped a lot here. It’s hard to imagine rules like
member-ordering to not be configurable. But another difference is more philosophical: The Dart team doesn’t add rules that they disagree with or don't see much value in (even if it’s clear to other teams). So, instead of wasting time trying to convince them, we came up with our own solution. And this has also shaped our philosophy — we are very open to different suggestions for rules, and add most of what our users ask us to.
H: I agree! I don’t like Dart lints for that, at least something like 80 chars per line should have configuration, or they should have added a rule for 120 at least a few years ago! Generally, DCM is really fast. What language and tools do you use to develop it?
D: DCM reuses some parts of the Dart analyzer (eg. parsing, element model resolution) and is written in Dart. VS Code extension and our backend are written in TypeScript and the IntelliJ / AS plugin is written in Kotlin. Aside from the IDE as the main tool for development, we use Codemagic and Github Actions to compile the tool and upload it to different package managers (Brew, Choco, and apt).
H: So, do you use DCM to validate DCM? 😅
D: Yes! I strongly believe that developers should dogfood their own creations in order to better understand users. Plus it helps to find stupid mistakes.
H: Could you briefly describe your journey in software engineering/development?
D: Well, my journey started at university with C# as my main language. I worked on a gaming side project with a friend, then got my first full-time job and combined it with university for 2 years before finally graduating. But when I first discovered HTML, CSS, and JS, something clicked inside me, and I really enjoyed working on the frontend. I think it’s mostly related to the ability to see the changes fast and the overall result of your work. So, I spent the next 1.5 years at an outsourcing company, working mostly on the frontend (and some other stuff, like Python backend). And then I found out about Dart. My first thought was, “hm, this is something not many people do, so why not try it.” As you can see, I really love challenges 😀. That's why I joined Wrike and continued my frontend journey, but this time with Dart. By the way, for those who remember that Wrike at some point decided to switch from Dart to TS, I was one of the main developers who worked on it. But it seems that this is a topic for another article. 😀 Afterwards, I joined the team to work on the browser as a frontend department lead until I decided it was time to work on DCM full-time.
H: Do you think that a technical/university background is important, or would you, on the contrary, go the self-taught route?
D: I think it's more important to learn how to learn new things and develop critical thinking. Where you get these skills is not that important. For me it was at the university, one particular professor to be exact. With these skills, you can learn basically anything, which gives you a huge advantage. On the other hand, you never know how specific knowledge can help you in the future. In this regard, life can be quite unpredictable. For example, if you only work on frontend/mobile, learning backend can help you see the bigger picture and make better decisions. And the university provides you with a great opportunity to learn the basics.
H: Where do you get inspiration for new lints? How long does one lint take to finish on average?
D: From different places. Some lint rules are based on experience, some are based on user feedback. Others are already implemented in other linters and we are simply porting them to Dart. The time it takes to implement a rule depends on the rule itself. Implementing and testing one rule can take on average from 30 minutes to 6-8 hours. The more flexible the rules, the longer it takes.
H: That’s actually pretty fast! What advantages does DCM have over packages that support creating their lints?
D: First of all, DCM is not only about lint rules. We provide additional features, like unused code and file detection, code metrics calculation, etc. And if we look closer into DCM’s goal — it’s mostly about saving time. Recreating the rules that DCM provides on your own will probably take more time for you to implement and maintain than just buying a license. Plus, the “linting” domain your team needs to get familiar with to support these rules is very different from the day-to-day Flutter developer job.
H: Do you plan a web admin for managing team licenses?
D: Yes. I initially wanted to avoid storing any user-related data (you can’t really expose the thing you don’t have), but this has a huge downside in managing licenses. So, an admin panel is a thing that we need to introduce to help our users with it.
H: Is there anything you can share about the future of DCM? Any interesting plans?
D: Well, as I mentioned here, I believe that there are plenty of things that can be improved in Dart static analysis. I'm not giving a specific release date yet, but making unused code and files to display their output in real-time in the IDE is one of the features we want to implement next. Then there are various plans for new commands, such as an AST-based code duplication check command that allows even renamed code to be marked as duplicate. Similarly, much remains to be done to improve the overall metrics experience. In addition, we receive a lot of feedback from users, so there will be something that we decide to implement as well.
H: That sounds great; I hope everything goes well. And lastly: Does pineapple belong on pizza?
D: For me, no. 🙂
Keeping code clean and bug-free should be one of the top priorities of a well-maintained project. DCM helps us with that a lot, and we suggest you try it too. And if you do, let us know what you think!